Suppongo che ciò sia dovuto alla natura di inferenza del tipo jdk 1.7.
Come forse già sapete, il metodo Arrays.asList(T ... elems)
è generico, ma raramente specificare esplicitamente il tipo-parametro che vorremmo il metodo con cui lavorare e quindi abbiamo affidamento la funzione inferenza di tipo del compilatore.
Così, quando il compilatore vede un Arrays.asList(Override.class)
dichiarazione sarà dedurre che il tipo di parametro per il metodo dovrebbe essere sostituito con Class<Override>
, vale a dire che avremmo un versione del metodo in questa forma:
public List<Class<Override>> asList(Class<Override> ... elems)
Tuttavia, se si esplicitamente impostato il parametro di tipo per il metodo di
List<Class<? extends Annotation>> l =
Arrays.<Class<? extends Annotation>>asList(Override.class);
poi il compilatore sarà effettivamente sapere qual è il tipo di parametro deve essere sostituita con e poi il versione del metodo .asList()
sarebbe:
public List<? extends Annotation> asList(Class<? extends Annotation> ... elems)
Ora questo compilerà bene, dal momento che Class<? extends Annotation>
è compatibile a Class<Override>
. In Java8, la funzione di inferenza del tipo è ulteriormente migliorata, quindi non è necessario impostare in modo esplicito il parametro type per il metodo .asList()
.
Tuttavia, il più domanda interessante va a
Perché List<Class<Override>>
non è compatibile con List<Class<? extends Annotation>>
?
Il java.lang.Class
è un final
uno, che aiuterebbe a rispondere alle seguenti due domande, la cui combinazione risponderà alla domanda di cui sopra.:)
Quindi,
- Che cosa un
List<Class<Override>>
significa?
List<Class<Override>>
significa che è possibile aggiungere solo istanze di Class<Override>
e nient'altro all'elenco. Il che è fantastico, sapendo che non possiamo nemmeno aggiungere sottoclassi Class<Override>
, dal momento che il tipo Class
è final
.
- Che cosa significa "
List<Class<? extends Annotation>>
"?
Questo tipo di List
rappresenta un'intera famiglia di liste di classi, che sono tutti sottoclassi di tipo Annotation
, il che significa che possiamo aggiungere con successo qualsiasi tipo di annotazione (per esempio, SuppressWarnings.class
, Override.class
, Documented.class
, ecc.) alla lista.
lascia supporre che il seguente esempio è stato effettivamente corretto:
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
Le due enormi problemi derivano dal fatto che stiamo cercando di aggiungere un po 'non Override
casi al overrides
, che è molto sbagliato.
Abbiamo un compilatore abbastanza intelligente che può effettivamente rilevare tali possibili problemi e lanciare un errore in fase di compilazione è il modo per impedirci di farlo.
Maggiori informazioni:
@kocko cosa hai usato java? Ho jdk1.7_079, ecco uno screenshot https://www.dropbox.com/s/p6gybp1jct19ehg/generics.jpg – AdamSkywalker
Ho giocato un po 'con questo e penso di aver trovato il motivo. Scriverò una risposta dopo un po '. –
Da testing, come in Java 7 è necessario parametrizzare la chiamata statica 'Array.> asList (Override.class); '. Con Java 8 non ho bisogno di –