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

时间:2020-03-05 18:49:57  来源:igfitidea点击:

假设我有以下课程:

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

我如何检查oE是同一个类?

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

我无法从(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);  
    }
}

回答

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

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

回答

" 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及类似内容。

回答

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