2016-05-16 25 views
7
Set<Object> removedObjs = new HashSet<>(); 
List<? extends MyEntity> delObjs = (List<? extends MyEntity>) new ArrayList<>(removedObjs); 

MyEntity è un'interfaccia marker.Java 8 Incompatible Types Errore

Sopra codice sta lavorando bene in (versione Java "1.7.0_91", per essere precisi), ma non in (versione Java "1.8.0_77")

In Java8, sto ottenendo la seguente eccezione :

incompatible types: ArrayList<Object> cannot be converted to List< ? extends MyEntity>

+4

Se si rimuove il simbolo '<>' si dovrebbe ricevere solo un avviso. Se non funziona in Java 8, probabilmente non avrebbe dovuto funzionare in Java 7. –

+0

Può essere compilatore nel mio ambiente JAVA1.8.0_92 in eclissi con solo avviso: Tipo sicurezza: cast non selezionato da ArrayList a elenco ma non può javac – andy

+3

Guardando il codice, sembra logico che non dovrebbe funzionare. basta inserire un 'removedObjs.add (" 42 ");' tra le due linee per vedere perché. – biziclop

risposta

8

Java 8 cambiato molto di inferenza di tipo e argomenti correlati. In quanto tale, non sorprende che alcuni casi limite (come le ombre oscure) improvvisamente non siano validi.

Qualunque sia la ragione è, è ancora possibile lanciare la vostra lista, ma è un po 'più brutta di prima:

(List<? extends MyEntity>) (List) new ArrayList<>(removedObjs);

Come sottolineato dal commento di Peter Lawrey, questo può essere scritto ancora più brevi come

(List) new ArrayList<>(removedObjs);

+0

La specifica del linguaggio Java scoraggia l'uso di tipi non elaborati eccetto che per lavorare con il codice precedente che precede i generici. Vedi anche http://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we-use-it – meriton

11

il codice dovrebbe essere né il lavoro in Java 7 né in Java 8, perché si sta cercando di lanciare un ArrayList<Object> (tipo restituito dal costruttore) per un 012.e non ha senso nemmeno in fase di compilazione (vedere this question). Ecco perché il compilatore si lamenta.

Il seguente codice compilerà:

Set<Object> removedObjs = new HashSet<>(); 
List<? extends Integer> delObjs = (List) new ArrayList<>(removedObjs); 

Tuttavia, il compilatore lancerà un messaggio di avviso in quanto si sta eseguendo una conversione non sicuro.

EDIT: Come @ Tom sottolinea:

"Il codice non dovrebbe funzionare in Java 7" Non dovrebbe, ma ha funzionato, perché i controlli del compilatore erano ancora un po 'difettoso in quella versione. Questo è stato corretto in Java 8, ecco perché ora fallisce.

+14

* "Il tuo codice non dovrebbe funzionare in java 7" * Non dovrebbe 't, ma ha funzionato, perché i controlli del compilatore erano ancora un po' difettosi in quella versione. Questo è stato corretto in Java 8, ecco perché ora fallisce. (solo una nota) – Tom

+0

^questo dovrebbe essere aggiunto alla risposta. –

+0

Usa i backtick ('\' ') se stai scrivendo il codice. – cst1992