Domanda sul casting di una classe in Java con generici

0

In Java 6

Class<? extends ArrayList<?>> a = ArrayList.class;

fornisce ed errore, ma

Class<? extends ArrayList<?>> b = (Class<? extends ArrayList<?>>)ArrayList.class;

dà un avvertimento.

Perché (a) un errore? Che cosa è, che Java ha bisogno di fare nel compito, se non il cast mostrato in (b)?

E perché non ArrayList compatibile con ArrayList<?> So che uno è "raw" e l'altro è "generico", ma cosa si può fare con un ArrayList<?> e non con un ArrayList , o viceversa?

    
posta Florian F 26.05.2014 - 23:46
fonte

2 risposte

2

Bene, una classe generica è per definizione non uguale a una classe raw. Quello che stai cercando ci nasconde il problema dell'istanziazione di ArrayLists (gli elenchi effettivi, non i loro tipi).

ArrayList raw = new ArrayList();

funzionerà e permetterà qualsiasi tipo di elemento, oggetti, primitive, qualsiasi cosa. D'altra parte,

ArrayList<?> generic = new ArrayList<?>();

non funzionerà poiché non è chiaro, in fase di compilazione, quali elementi effettivi saranno presenti nella lista. Quindi, per rendere la lista (quasi) ampiamente utilizzabile come quella grezza, puoi istanziarla in questo modo:

ArrayList<?> generic = new ArrayList<Object>();

(Ciò manterrà solo oggetti reali, però, senza primitive.)

generic e raw non saranno mai uguali dal punto di vista del tipo e non avrà senso che siano uguali.

Che cosa puoi fare con i tipi generici anziché quelli grezzi? Bene, sii al sicuro in fase di compilazione. :) Viceversa? Usa le primitive (i tipi generici devono ereditare da Object quali primitive non lo fanno).

    
risposta data 27.05.2014 - 22:28
fonte
1

Anche se è vero che la cancellazione dei tipi di Java significa che i generici sono compilati in classi raw, significano ancora qualcosa alla compilation. Il punto fondamentale dei generici è quello di applicare il casting coerente al momento della compilazione, quindi non c'è da meravigliarsi se non si può lanciare implicitamente da Class<ArrayList> a Class<? extends ArrayList<?>> anche se sono esattamente dello stesso tipo in fase di runtime.

In altre parole - ottieni un errore di compilazione perché l'intero punto dei generici in Java è di fornire un "casting" implicito sicuro in questi casi e genera un errore di compilazione quando c'è un tipo generico di mancata corrispondenza.

    
risposta data 27.05.2014 - 00:04
fonte

Leggi altre domande sui tag