2012-01-19 9 views
5

Ho una domanda sull'utilizzo di generici con le collezioni.Raccolta con generici

ArrayList<Integer> al=new ArrayList<Integer>(); 

sappiamo che la linea di cui sopra significa che ArrayListal è limitato per contenere solo numeri interi. Quindi la riga seguente dà un errore di compilazione:

al.add("wwww"); 

Ma non capisco che cosa significa la riga sotto,

ArrayList al=new ArrayList<Integer>(); 

Dove non diamo ArrayList<Integer> sul lato sinistro pur dichiarando. Ora la seguente riga non dà un errore di compilazione:

al.add("wwww"); 

Quindi, se dichiaro come

ArrayList al=new ArrayList<Integer>(); 

che significa a1 può accettare qualsiasi tipo?

Qual è la differenza tra queste due dichiarazioni?

risposta

5

Con questo codice:

ArrayList al = new ArrayList<Integer>(); 
a1.add("www"); 

il compilatore genera un messaggio di avviso (che si dovrebbe prestare attenzione!), Ma il codice verrà eseguito senza errori. Il problema si verifica quando si estrae i dati da a1. Se si "sa" che contiene Integer valori, si può solo fare questo:

Integer val = (Integer) a1.get(index); 

Ma quando si preme l'elemento "www" si sta andando ad ottenere un ClassCastException. I generici hanno lo scopo di spostare tali errori per compilare il tempo invece di costringere il povero sviluppatore a rintracciare come un valore String è finito in quell'elenco di array Integer.

9

Quest'ultima dichiarazione (senza tipo generico) è obsoleta e deprecata. Non dovresti usarlo, compila solo per compatibilità con le versioni precedenti. Gli IDE moderni genereranno avvertimenti qui.

Si noti inoltre che Java impone solo i tipi generici in fase di compilazione, quindi tecnicamente è possibile aggiungere un tipo errato a una raccolta con alcuni cast aggiuntivi. Ecco perché è meglio stare con i generici tutto il tempo e non ignorarli.

+1

... e il tuo IDE (se ne stai usando uno) probabilmente mostra un avviso per questo. – Axel

+0

@Axel: +1. Indipendentemente ho aggiunto lo stesso commento alla mia risposta, devi credermi ;-). –

+0

Per alcune ragioni a partire da 7 le persone netbeans disabilitate mostrano gli avvisi standard di javac per impostazione predefinita. (e un significativo aumento nel dire agli stagisti "aggiustare gli avvisi di tipo non elaborato.") – Affe

0

Quest'ultima dichiarazione è fondamentalmente lo stesso:

ArrayList<Object> al=new ArrayList<Object>(); 

accettando così qualsiasi oggetto. Non dovrebbe essere usato ed è possibile utilizzarlo in modo che Java sia compatibile con le versioni precedenti (pre Java 1.5).

0

si dovrebbe scrivere in questo modo ArrayList<Integer> al=new ArrayList<Integer>(); per evitare di aggiungere alla lista oggetti con un altro tipo perché vedrete il tempo di compilazione dell'errore. Ovviamente puoi usare ArrayList al=new ArrayList<Integer>(); ma devi fare attenzione. In altre parole, usa sempre il primo: D

0

I generici sono implementati mediante cancellazione del tipo: le informazioni di tipo generico sono presenti solo al momento della compilazione, dopodiché vengono cancellate dal compilatore. Quindi, la dichiarazione di ArrayList al compilatore accetta qualsiasi tipo. Ecco java doc su questo argomento.

0

Questo tipo di dichiarazione è consentito per la retrocompatibilità. Così si può per esempio si passa elenco generico al metodo dalla libreria vecchio stile Wich accetta lista unica cruda:

List<Integer> list = new ArrayList<Integer>(); 
OldStyledClass.method(myArray); 

in cui il metodo è dichiarato come:

public static void method(List list)... 

In questo caso avete un po 'speciale metodi di utilità in java.util.Collections. Così si può passare a questa lista protetta metodo:

OldStyledClass.method(Collections.checkedList(myArray, Integer.class)); 

Se il metodo cercherà di mettere in lista il tuo oggetto di qualche altro tipo otterrete ClassCastException dispensati.