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

我的未来我决定 提交于 2020-01-22 08:28:12

问题


Let's say I have the following class:

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

How would I check that o is the same class as E?

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.

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


回答1:


An instance of Test has no information as to what E is at runtime. So, you need to pass a Class<E> to the constructor of 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.isAssignableFrom instead of the Class comparison. Note, E will need to be a non-generic type, for the same reason Test needs the Class object.

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




回答2:


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



回答3:


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



回答4:


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.

so your sameClassAs method should look like:

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


来源:https://stackoverflow.com/questions/51582/java-generics-comparing-the-class-of-object-o-to-e

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!