Экземпляр 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
объект.
Для примеров в API Java, см. java.util.Collections.checkedSet
и подобный.
Метод, который я всегда использовал, ниже. Это - боль и немного ужасный, но я не нашел лучший. Необходимо передать тип класса через конструкции, как тогда, когда Дженерики являются информацией о скомпилированном классе, потерян.
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);
}
}
Я мог только сделать его работающий как это:
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);
}
}
Я просто пытался сделать то же самое, и я понял одну хитрость: вы можете попробовать приведение, и если приведение не выполнено, 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;
}
}