Java泛型:将对象o类与<;E>;

Java泛型:将对象o类与<;E>;,java,generics,Java,Generics,假设我有以下课程: public class Test<E> { public boolean sameClassAs(Object o) { // TODO help! } } 我无法从(Object o)更改方法签名,因为我正在重写一个超类,因此无法选择我的方法签名 我也不希望尝试强制转换,然后在失败时捕获生成的异常。我只能让它这样工作: public class Test<E> { private E e;

假设我有以下课程:

public class Test<E> {
    public boolean sameClassAs(Object o) {
        // TODO help!
    }
}
我无法从
(Object 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);  
    }
}
公共类测试{
私人E;
公共无效集(E){
这个。e=e;
}
公共布尔sameClassAs(对象o){
返回(o.getClass().equals(e.getClass());
}
公共布尔sameclassa2(对象o){
返回e.getClass().isInstance(o);
}
}

下面是我一直使用的方法。这是一个痛苦和有点丑陋,但我还没有找到一个更好的。您必须在构造时传递类类型,就像编译泛型时丢失类信息一样

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);
    }
}
公共类测试{
私人课堂;
公开考试(课堂){
this.clazz=clazz;
}
公共布尔sameClassAs(对象o){
返回此.clazz.isInstance(o);
}
}

测试的
实例没有关于运行时
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;
    }
}
公共类测试{
私人期末班;
公开考试(课堂){
if(clazz==null){
抛出新的NullPointerException();
}
this.clazz=clazz;
}
//要使客户的工作更轻松,请执行以下操作:
公共静态测试创建(类clazz){
返回新测试(clazz);
}
公共布尔sameClassAs(对象o){
返回o!=null&&o.getClass()==clazz;
}
}
如果需要“instanceof”关系,请使用
Class.isAssignableFrom
而不是
Class
比较。注意,
E
必须是非泛型类型,原因与
Test
需要
Class
对象相同


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

我只是想做同样的事情,我刚刚意识到的一个巧妙的技巧是,您可以尝试强制转换,如果强制转换失败,将抛出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;
    }
}

不会的。这是一个未经检查的演员阵容。它永远不会抛出异常。在运行时,“t”的擦除类型为E,这只是对象,所以并没有执行强制转换。您是正确的。这将节省我以后大量的疑难解答,因为编译似乎很好。我宁愿将这些类与equals进行比较。或者使用==?有特殊原因吗?它们是等价的。IMO==更容易阅读(尽管它确实意味着读者必须知道类型)。在内联之前,速度稍微快一点。现在,我似乎没有测试过的是一个空的clazz。
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;
    }
}