Java泛型:将对象o的类与<E>进行比较

Java泛型:将对象o的类与<E>进行比较

Java Generics: Comparing the class of Object o to

假设我有以下课程:

1
2
3
4
5
public class Test<E> {
    public boolean sameClassAs(Object o) {
        // TODO help!
    }
}

如何检查oE是同一类?

1
2
3
Test<String> test = new Test<String>();
test.sameClassAs("a string"); // returns true;
test.sameClassAs(4); // returns false;

由于无法覆盖超类,因此无法从(Object o)更改方法签名,因此不要选择我的方法签名。

我也宁愿不尝试尝试强制转换,然后在异常失败时捕获所产生的异常。


Test的实例不了解什么E在运行时。因此,您需要将Class传递给Test的构造函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Test<E> {
    private final Class<E> clazz;
    public Test(Class<E> clazz) {
        if (clazz == null) {
            throw new NullPointerException();
        }
        this.clazz = clazz;
    }
    // To make things easier on clients:
    public static < T > Test< T > create(Class< T > clazz) {
        return new Test< T >(clazz);
    }
    public boolean sameClassAs(Object o) {
        return o != null && o.getClass() == clazz;
    }
}

如果需要" instanceof"关系,请使用Class.isAssignableFrom而不是Class比较。注意,出于相同的原因,E将需要是非通用类型,Test需要Class对象。

有关Java API中的示例,请参见java.util.Collections.checkedSet及类似内容。


我一直使用的方法如下。这是一种痛苦并且有点丑陋,但是我还没有找到更好的选择。您必须在构造时传递类类型,因为在编译泛型时,类信息会丢失。

1
2
3
4
5
6
7
8
9
public class Test<E> {
    private Class<E> clazz;
    public Test(Class<E> clazz) {
       this.clazz = clazz;
    }
    public boolean sameClassAs(Object o) {
        return this.clazz.isInstance(o);
    }
}


我只能使它像这样工作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Test<E> {  

    private E e;  

    public void setE(E e) {  
        this.e = e;  
    }

    public boolean sameClassAs(Object o) {  

        return (o.getClass().equals(e.getClass()));  
    }

    public boolean sameClassAs2(Object o) {  
        return e.getClass().isInstance(o);  
    }
}

我只是想做同样的事情,我刚刚意识到的一个巧妙技巧就是可以尝试强制转换,如果强制转换失败,将抛出ClassCastException。您可以捕获该消息,然后执行任何操作。

因此您的sameClassAs方法应如下所示:

1
2
3
4
5
6
7
8
9
10
11
public boolean sameClassAs(Object o) {
    boolean same = false;
    try {
        E t = (E)o;
        same = true;
    } catch (ClassCastException e) {
        // same is false, nothing else to do
    } finally {
        return same;
    }
}


推荐阅读