Java 泛型:比较 Object o 和 <E> 的类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/51582/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 07:41:05  来源:igfitidea点击:

Java Generics: Comparing the class of Object o to <E>

javagenerics

提问by SCdF

Let's say I have the following class:

假设我有以下课程:

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

How would I check that ois the same class as E?

我将如何检查oE?

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

I can't change the method signature from (Object o)as I'm overridding a superclass and so don't get to choose my method signature.

我无法更改方法签名,(Object o)因为我正在覆盖超类,因此无法选择我的方法签名。

I would also rather not go down the road of attempting a cast and then catching the resulting exception if it fails.

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

采纳答案by Tom Hawtin - tackline

An instance of Testhas no information as to what Eis at runtime. So, you need to pass a Class<E>to the constructor of Test.

的实例Test没有关于E运行时什么的信息。因此,您需要将 a 传递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;
    }
}

If you want an "instanceof" relationship, use Class.isAssignableFrominstead of the Classcomparison. Note, Ewill need to be a non-generic type, for the same reason Testneeds the Classobject.

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

For examples in the Java API, see java.util.Collections.checkedSetand similar.

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

回答by Slartibartfast

I could only make it working like this:

我只能让它像这样工作:

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

回答by Nick Fortescue

The method I've always used is below. It is a pain and a bit ugly, but I haven't found a better one. You have to pass the class type through on construction, as when Generics are compiled class information is lost.

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

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

回答by Ayman

I was just trying to do the same thing, and one neat trick i just realized is that you can can try a cast, and if the cast fails, ClassCastException will be thrown. You can can catch that, and do whatever.

我只是想做同样的事情,我刚刚意识到的一个巧妙技巧是您可以尝试强制转换,如果强制转换失败,将抛出 ClassCastException。你可以抓住它,做任何事情。

so your sameClassAs method should look like:

所以你的 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;
    }
}