Это хорошая практика, чтобы заменить класс на класс <? расширяет объект> чтобы избежать предупреждений? - PullRequest
9 голосов
/ 16 декабря 2008

В моем множестве мест в моем коде есть что-то вроде этого:

public Class mySpecialMethod() {
  return MySpecialClass.class;
}

, что вызывает предупреждение

Класс является необработанным типом. Ссылки на универсальный тип Class должен быть параметризованный.

Но, если я заменю

Class

с

Class<? extends Object>

предупреждение уходит.

Хорошо ли это простая практика, или она может вызвать проблемы позже?

Ответы [ 4 ]

15 голосов
/ 16 декабря 2008

Это правильно, только если на самом деле нет общего базового класса или интерфейса, который должен представлять объект Class.

Также Class<?> фактически совпадает с Class<? extends Object>.

6 голосов
/ 16 декабря 2008

В зависимости от того, чего вы хотите достичь, вы можете быть еще точнее:

public Class<MySpecialClass> mySpecialMethod() {
  return MySpecialClass.class;
}
6 голосов
/ 16 декабря 2008

Да, это совершенно верно.

Требуется указать тип. И если вы не можете, вы должны указать шаблон.

Дополнительная информация: Спецификация языка Java: параметризованные типы

4 голосов
/ 16 декабря 2008

Не совсем программист на Java, но прочитайте несколько хороших статей о дженериках.

Да, вы должны добавить подстановочный знак или точный тип (Class<MySpecialClass>), чтобы добавить безопасность. Причина в том, что класс является универсальным. Таким образом, Class<Bar> и Class<Foo> одинаковы после удаления их параметра общего типа. Все они становятся Class, так называемым необработанным типом. Это стирание происходит при компиляции. Несколько примеров, иллюстрирующих это, где компилятор помогает вам с автоматическим приведением (обработка краткости исключена для краткости):

class Mine { }

class Vara {
    public static void main(String... args) {
        { // works. translated to Mine m = (Mine) c.newInstance();
            Class<Mine> c = Mine.class;
            Mine m = c.newInstance();
        }
        { // doesn't work. need a cast: Mine m = (Mine) c.newInstance();
            Class c = Mine.class; // also Class<?> or Class<? extends Object>
            Object o = c.newInstance(); // but this works. pointing to a Mine
            Mine m = (Mine) c.newInstance(); // needs a manual cast
        }
    }
}

Говоря Class<?> (и эквивалент Class<? extends Object>), вы говорите компилятору, что вам действительно нужен класс, у которого T - объект, и который случайно не использовал необработанный тип. Но это не добавит удобство. Все, что делают дженерики, - это вставляют для вас автоматическое приведение, приведение от Object к типу назначения. Обобщения являются одинаковыми, независимо от того, используются ли они с типом U или с типом T во время выполнения по причинам совместимости со старыми версиями Java.

...