假设我有以下课程:

public class Test<E> {
    public boolean sameClassAs(Object o) {
        // TODO help!
    }
}

我该如何检查 o 是同一个班级 E?

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

我无法更改方法签名 (Object o) 因为我正在重写超类,所以不要选择我的方法签名。

我也不想尝试进行强制转换,然后在失败时捕获由此产生的异常。

有帮助吗?

解决方案

一个实例 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;
    }
}

如果您想要“instanceof”关系,请使用 Class.isAssignableFrom 而不是 Class 比较。笔记, E 出于同样的原因,需要是非泛型类型 Test 需要 Class 目的。

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

其他提示

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

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);
    }
}

我只能让它像这样工作:

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 方法应该如下所示:

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;
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top