Не совсем программист на 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.