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

Tags: generics java
By : SCdF
Source: Stackoverflow.com
Question!

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.

By : SCdF


Answers

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.



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;
    }
}
By : Ayman


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


This video can help you solving your question :)
By: admin