Java Generics:将Object o的类与<E>进行比较

SCd*_*CdF 25 java generics

假设我有以下课程:

public class Test<E> {
    public boolean sameClassAs(Object o) {
        // TODO help!
    }
}
Run Code Online (Sandbox Code Playgroud)

我怎么检查那o是同一个班级E

Test<String> test = new Test<String>();
test.sameClassAs("a string"); // returns true;
test.sameClassAs(4); // returns false;
Run Code Online (Sandbox Code Playgroud)

我无法更改方法签名,(Object o)因为我覆盖了超类,所以不要选择我的方法签名.

我也宁愿不去尝试一个演员然后如果失败就抓住结果异常.

Tom*_*ine 27

一个实例Test没有关于E运行时的信息.所以,你需要传递Class<E>给Test的构造函数.

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您想要"instanceof"关系,请使用Class.isAssignableFrom而不是Class比较.注意,E需要是非泛型类型,出于同样的原因Test需要该Class对象.

有关Java API中的示例,请参阅java.util.Collections.checkedSet和类似.


Nic*_*cue 10

我一直使用的方法如下.这是一种痛苦,有点难看,但我没有找到更好的.你必须在构造时传递类类型,因为当泛型被编译时类信息丢失了.

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);
    }
}
Run Code Online (Sandbox Code Playgroud)