Qual è la differenza tra l’elenco dei tipi jolly illimitati E l’elenco dei tipi non elaborati?

Potresti aiutarmi a capire la differenza tra l’ elenco dei caratteri jolly illimitati e l’ elenco dei tipi non elaborati ?

List b; // unbounded wildcard type List a; // raw type 

Insieme a questo qualcuno può aiutarmi a capire cosa è un elenco di parametri di tipo limitato ?

 List c; 

Ecco un riassunto dei tre:

  • List : una lista senza parametro di tipo. È una lista i cui elementi sono di qualsiasi tipo – gli elementi possono essere di tipi diversi .

  • List : Un elenco con un parametro di tipo illimitato. I suoi elementi sono di un tipo specifico, ma sconosciuto; gli elementi devono essere tutti dello stesso tipo .

  • List : un elenco con un parametro di tipo chiamato T Il tipo fornito per T deve essere di un tipo che estende E , o non è un tipo valido per il parametro.

Si dovrebbe davvero guardare a Java efficace, articolo 23: non utilizzare i tipi non elaborati nel nuovo codice.

Per usare l’esempio di quel libro, considera il seguente esempio … cosa succede se hai una collezione in cui non ti interessa quali tipi di elementi ci sono dentro. Ad esempio, vuoi vedere quanti elementi sono in comune tra due set. Si potrebbe venire con il seguente:

 public static int numElementsInCommon(Set s1, Set s2) { int result = 0; for (Object o : s1) { if (s2.contains(o)) { ++result; } } return result; } 

Questo esempio, mentre funziona, non è una buona idea da usare a causa dell’uso di tipi non elaborati. I tipi non sono affatto sicuri del tipo … si potrebbe finire per modificare il set in un modo che non è sicuro e corrotto il programma. Invece, sii sul lato della caucanvas e usa l’alternativa sicura del tipo:

 public static int numElementsInCommon(Set s1, Set s2) { int result = 0; for (Object o : s1) { if (s2.contains(o)) { ++result; } } return result; } 

La differenza è che puoi aggiungere null a un Set , E NON puoi assumere nulla riguardo l’elemento che estrai da un Set . Se utilizzi un Set non Set , puoi aggiungere tutto ciò che desideri. Il metodo numElementsInCommon è un buon esempio in cui non è nemmeno necessario aggiungere nulla e non è necessario assumere nulla su ciò che è nel set. Ecco perché è un buon candidato per l’utilizzo del ? jolly.

Spero che questo ti aiuti. Leggi tutto l’articolo in Java efficace e diventerà davvero chiaro.

Per rispondere alla seconda parte della tua domanda … ricorda che ti ho detto quando usi il ? jolly, non puoi assumere nulla sull’elemento che estrai dal set? Che cosa succede se hai bisogno di fare una supposizione sull’interfaccia dell’object che hai rimosso dal set. Ad esempio, supponiamo di voler tenere traccia di un insieme di cose interessanti.

 public interface Cool { // Reports why the object is cool void cool(); } 

Quindi potresti avere un codice come questo:

 public static void reportCoolness(Set s) { for (Object item : s) { Cool coolItem = (Cool) item; coolItem.cool(); } } 

Questo non è sicuro per tipo … devi assicurarti di aver passato un set con solo oggetti Cool . Per risolvere il problema, potresti dire:

 public static void reportCoolness(Set s) { for (Cool coolItem : s) { coolItem.cool(); } } 

È fantastico! Fa esattamente quello che vuoi ed è sicuro. Ma cosa succede se in seguito hai questo:

 public interface ReallyCool extends Cool { // Reports why the object is beyond cool void reallyCool(); } 

Dal momento che tutti ReallyCool oggetti ReallyCool sono Cool , si dovrebbe essere in grado di fare quanto segue:

 Set s = new HashSet(); // populate s reportCoolness(s); 

Ma non puoi farlo perché i generici hanno la seguente proprietà: Supponiamo che B sia una sottoclass di A , quindi Set NON è una sottoclass di Set . Il discorso tecnico per questo è “I tipi generici sono invarianti”. (Al contrario di covariante).

Per fare in modo che l’ultimo esempio funzioni, devi creare un Set colando (in sicurezza) ogni elemento nel Set . Per evitare che i clienti della tua API passino attraverso questo brutto codice non necessario, puoi semplicemente rendere il metodo reportCoolness più flessibile come questo:

 public static void reportCoolness(Set s) { for (Cool coolItem : s) { coolItem.cool(); } } 

Ora il tuo metodo prende qualsiasi Set che contenga elementi Cool o qualsiasi sottoclass di Cool . Tutti questi tipi aderiscono al Cool api … quindi possiamo tranquillamente chiamare il metodo cool() su qualsiasi elemento

Ha senso? Spero che questo ti aiuti.

Sulla prima domanda, la differenza tra List e List :

Una differenza significativa tra i due è che quando si ha un carattere jolly come tipo, il tipo di Collection è sconosciuto, quindi il metodo add genererà un errore in fase di compilazione.

Puoi ancora ottenere valori List , Ma hai bisogno di un cast esplicito.