Я бы предположил, что это из-за характера вывода типа jdk 1.7.
Как вы уже знаете, метод Arrays.asList(T ... elems)
универсальна, но мы редко явно указать тип-параметр, который мы хотели бы метод работать и, таким образом, мы полагаться на тип логического вывода функции компилятора.
Итак, когда компилятор видит в Arrays.asList(Override.class)
заявлении будет вывод, что тип-параметр для метода следует заменить Class<Override>
, то есть мы бы версии метода в следующем виде:
public List<Class<Override>> asList(Class<Override> ... elems)
Однако, если вы явно установить параметр типа для метода
List<Class<? extends Annotation>> l =
Arrays.<Class<? extends Annotation>>asList(Override.class);
, то компилятор будет на самом деле знает, что тип-параметр должен быть заменен, а затем версия метода .asList()
будет:
public List<? extends Annotation> asList(Class<? extends Annotation> ... elems)
Теперь это будет компилироваться, так как Class<? extends Annotation>
совместим до Class<Override>
. В Java8 функция вывода типов улучшается еще больше, так что вам не нужно явно устанавливать параметр типа для метода .asList()
.
Однако более интересный вопрос идет в
Почему List<Class<Override>>
не совместим с List<Class<? extends Annotation>>
?
The java.lang.Class
является final
один, который помог бы ответить на следующие два вопроса, сочетание которых будет отвечать на поставленный выше вопрос.:)
Так,
- Что делает
List<Class<Override>>
значит?
List<Class<Override>>
означает, что мы можем добавлять только экземпляры Class<Override>
и ничего больше, кроме этого. Это здорово, зная, что мы не можем даже добавить подклассы Class<Override>
, так как тип Class
- это final
.
- Что означает
List<Class<? extends Annotation>>
?
Этого типа List
представляет собой целую семьи списков классов, все из которых являются подклассами типа Annotation
, что означает, что мы можем успешно добавить любой тип аннотации (например, SuppressWarnings.class
, Override.class
, Documented.class
и т. д.) в список.
Давайте предположим, что следующий пример был на самом деле правильно:
List<Class<Override>> overrides = Arrays.asList(Override.class);
List<Class<? extends Annotation>> annotations = new ArrayList<>();
annotations = overrides;
annotations.add(SuppressWarnings.class); //HUGE PROBLEM
annotations.add(Documented.class); //ANOTHER HUGE PROBLEM
Две огромные проблемы возникают из-за того, что мы пытаемся добавить Непро- Override
экземпляры в overrides
, что очень неправильно.
У нас есть достаточно умный компилятор, который может фактически обнаружить такие возможные проблемы, и бросать ошибку времени компиляции - это способ помешать нам сделать это.
Подробнее:
@kocko какой java вы использовали? У меня есть jdk1.7_079, вот скриншот https://www.dropbox.com/s/p6gybp1jct19ehg/generics.jpg – AdamSkywalker
Я немного поиграл с этим, и я думаю, что нашел причину. Через некоторое время я напишу ответ. –
От тестирования, похоже, в Java 7 вам необходимо параметризовать статический вызов 'Arrays.> asList (Override.class); '. С Java 8 мне не нужно было –