Java Generics: Сравнение класса Object o с <E> - PullRequest
24 голосов
/ 09 сентября 2008

Допустим, у меня есть следующий класс:

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

Как мне проверить, что o - это тот же класс, что и E?

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

Я не могу изменить сигнатуру метода с (Object o), так как я переопределяю суперкласс и поэтому не могу выбрать сигнатуру метода.

Я бы тоже не стал идти по дороге, пытаясь выполнить приведение, а затем перехватить полученное исключение в случае сбоя.

Ответы [ 4 ]

26 голосов
/ 09 сентября 2008

Экземпляр 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 и аналогичных.

9 голосов
/ 09 сентября 2008

Метод, который я всегда использовал ниже. Это боль и немного уродливо, но я не нашел лучшего. Вы должны передать тип класса при построении, как при компиляции обобщенных данных информация о классе теряется.

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);
    }
}
2 голосов
/ 09 сентября 2008

Я мог только заставить его работать так:

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);  
    }
}
0 голосов
/ 19 апреля 2009

Я просто пытался сделать то же самое, и я понял одну хитрую хитрость: вы можете попробовать выполнить приведение, и в случае сбоя произойдет выброс 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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...