Zakładam, że dzieje się tak z powodu natury wnioskowania typu jdk 1.7.
Jak być może wiesz już, metoda Arrays.asList(T ... elems)
jest nazwą rodzajową, ale rzadko wyraźnie określić typu parametru, który chcielibyśmy metody do pracy i mamy zatem polegać na funkcję rodzaj wnioskowania kompilatora.
Więc, gdy kompilator widzi oświadczenie Arrays.asList(Override.class)
będzie wywnioskować, że parametr typu dla metody należy zastąpić Class<Override>
, to znaczy, że mamy wersję metody w tej formie:
public List<Class<Override>> asList(Class<Override> ... elems)
jednak jeśli jawnie ustawić parametr typu dla metody
List<Class<? extends Annotation>> l =
Arrays.<Class<? extends Annotation>>asList(Override.class);
następnie kompilator będzie rzeczywiście wiedzieć, co typu parametr musi być zastąpiony, a następnie wersja metody .asList()
byłoby:
public List<? extends Annotation> asList(Class<? extends Annotation> ... elems)
Teraz będzie to skompilować grzywny, ponieważ Class<? extends Annotation>
jest kompatybilny do Class<Override>
. W języku Java 8 funkcja wnioskowania o typ jest jeszcze bardziej ulepszona, dzięki czemu nie trzeba jawnie ustawiać parametru typu dla metody .asList()
.
Jednak więcej ciekawe pytanie idzie do
Dlaczego List<Class<Override>>
nie jest kompatybilny z List<Class<? extends Annotation>>
?
The java.lang.Class
jest final
jeden, który pomoże odpowiedzieć na następujące dwa pytania, kombinacja, która odpowie na powyższe pytanie.:)
Więc
- Co robi
List<Class<Override>>
oznacza?
List<Class<Override>>
oznacza, że możemy dodać tylko instancje Class<Override>
i nic innego do listy. Co jest wspaniałe, wiedząc, że nie możemy nawet dodać podklas Class<Override>
, ponieważ typ Class
to final
.
- Co oznacza
List<Class<? extends Annotation>>
?
Ten typ List
reprezentuje cały rodzinę list klas, z których wszystkie są podklasy rodzaju Annotation
, co oznacza, że możemy z powodzeniem dodać dowolny typ adnotacji (na przykład, SuppressWarnings.class
, Override.class
, Documented.class
itp.) do listy.
Pozwala przypuszczać, że następujący przykład był rzeczywiście poprawne:
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
Dwa ogromne problemy pochodzą z faktu, że próbujesz dodać pewne dopuszczalne Override
instancji do overrides
, co jest bardzo złe.
Mamy wystarczająco inteligentny kompilator, który może rzeczywiście wykryć takie potencjalne problemy, a wyrzucenie błędu podczas kompilacji jest sposobem, aby uniemożliwić nam to.
Więcej informacji:
@kocko jakiego używałeś java? Mam jdk1.7_079, oto zrzut ekranu https://www.dropbox.com/s/p6gybp1jct19ehg/generics.jpg – AdamSkywalker
Grałem z tym trochę i myślę, że znalazłem przyczynę. Napiszę odpowiedź po chwili. –
Z testowania, wygląda jak w Java 7, musisz sparametryzować wywołanie statyczne 'Tablice.> asList (Override.class); '. Z Java 8 nie potrzebowałem –