2011-01-25 15 views
16

Le persone dicono che il metodo asList converte l'array in elenco e non lo copia, quindi ogni modifica in "a lista" si rifletterà in "a". Quindi aggiungere nuovi valori in "a lista" è illegale, poiché la matrice ha dimensioni fisse.Arrays.asList() dubbio?

Tuttavia, il metodo asList() restituisce ArrayList<T>. Come il compilatore differenzia la linea 3 da 5. La riga 3 mi dà un'eccezione (UnsupportedOperationException).

 String[] a = {"a","b","c","d"};//1 
     List<String> aList = Arrays.asList(a);//2 
     aList.add("e");//3 
     List<String> b = new ArrayList<String>();//4 
     b.add("a");//5 
+5

Non importa cosa "dicono". Importa ciò che dice * Javadoc *. – EJP

risposta

3

È un'eccezione e non un errore del compilatore. Viene lanciato quando il programma viene eseguito e non al momento della compilazione. Fondamentalmente la classe effettiva che Arrays.asList restituirà ha un throw UnsupporteOperationException all'interno del metodo add().

Per essere più specifici Arrays.asList restituirà una classe interna definita all'interno della classe Arrays derivato da AbstractList e non implementa il metodo add. Il metodo add da AbstractList sta effettivamente generando l'eccezione.

33

Questa implementazione di elenco ricevuta da Arrays.asList è una vista speciale sull'array: non è possibile modificarne le dimensioni.

Il tipo di reso di Arrays.asList() è java.util.Arrays.ArrayList che viene spesso confuso con java.util.ArrayList. Arrays.ArrayList mostra semplicemente l'array come un elenco.

+3

+1 Penso che questo sia fondamentalmente il nocciolo della domanda. L'OP vede che il tipo restituito è ArrayList e si chiede perché si comporta in modo diverso da ArrayList. Domanda perfettamente valida –

+0

Andreas_D, il tipo restituito da 'Arrays.asList (...)' è 'java.util.List' e non' java.util.Arrays.ArrayList'. –

3

Si presume che Arrays.asList() restituisca un ArrayList, ma non è questo il caso. Arrays.asList() restituisce un'implementazione List non specificata. Tale implementazione semplicemente getta un UnsupportedOperationException su ciascun metodo non supportato.

4

asList() non restituisce un java.util.ArrayList, restituisce un java.util.Arrays$ArrayList. Questa classe non si estende nemmeno a java.util.ArrayList, quindi il suo comportamento può essere (ed è) completamente diverso.

Il metodo add() è ereditato da java.util.AbstractList, che per impostazione predefinita gira solo UnsupportedOperationException.

+0

No, asList restituisce una lista. Quello che stai descrivendo potrebbe essere vero per una specifica implementazione Java, ma non è qualcosa su cui puoi fare affidamento. – jarnbjo

+0

@jarnbjo - Questo vale sia per Sun Java che per GNU Classpath e probabilmente per qualsiasi altra implementazione in quanto è il modo più semplice per farlo. Poiché la domanda riguardava il modo in cui il compilatore può dire, penso che un esempio concreto sarebbe più facile da capire. – OrangeDog

0

asList restituisce un elenco di dimensioni fisse, in modo che non è possibile aggiungere nuovi elementi ad esso. Poiché la lista restituita è in realtà una "vista" dell'array da cui è stata creata ('a' nel tuo caso), ha senso che non sarai in grado di aggiungere elementi - proprio come non puoi aggiungere elementi a un array. Vedere la documentazione per asList

9

Read again, il tipo di Arrays.asList è:

public static <T> List<T> asList(T... a) 

in cui si afferma chiaramente che asList restituisce un oggetto che implementa l'interfaccia java.util.List, da nessuna parte si dice che restituirà un'istanza della classe java.util.ArrayList.

Avanti, si noti che la documentazione sul List.add dice:

boolean add (E e)

          Aggiunge l'elemento specificato alla fine di questa lista (operazione opzionale).

Tecnicamente, ogni volta che si utilizza una variabile di tipo List (invece di ArrayList), si dovrebbe sempre fare attenzione ad aspettare che questo metodo può lanciare UnsupportedOperationException. Se sei sicuro che riceverai solo un'implementazione di List che ha sempre la semantica corretta di .add(), allora puoi omettere il controllo a rischio di un bug quando la tua ipotesi è invalidata.

1

La chiave di questo è l'implementazione List restituito da

List<String> aList = Arrays.asList(a); 

Se si guarda il codice sorgente in Arrays si vedrà che essa contiene una classe statica privata interna ArrayList. Questo non è lo stesso di java.util.ArrayList.

5

Manoj,

il tipo di ritorno di Arrays.List qualche sconosciuta implementazione interna dell'interfaccia List e non java.util.ArrayList, in modo da poter assegnare solo un tipo di elenco.

Se si assegna a un ArrayList per esempio che vi darà tempo di compilazione errore "Tipo non corrispondente: non è possibile convertire da List a ArrayList"

ArrayList<String> aList = Arrays.asList(a);// gives Compile time error 

Dal Javadoc "Arrays.asList Restituisce un fisso elenco delle dimensioni supportato dall'array specificato. (Le modifiche all'elenco restituito "write through" all'array.) "significa che viene fornita solo una visualizzazione elenco della matrice che viene creata IMO in fase di runtime e naturalmente non è possibile modificare la dimensione di un array in modo da non poter cambiare anche la dimensione di "Arrays.asList".

IMO l'implementazione interna di Arrays.asList ha tutti i metodi implementati che possono cambiare la dimensione della matrice come -

void add(E e) 
{ 
//some unknown code 
throw(java.lang.UnsupportedOperationException); 
} 

così ogni volta che si tenta di modificare la dimensione della matrice si getta l'UnsupportedOperationException.

Ancora se si desidera aggiungere alcuni nuovi elementi a un ArrayList utilizzando una sintassi, è possibile farlo con la creazione di una sottoclasse di Arraylist (preferibilmente utilizzando sottoclasse anonima di ArrayList). È possibile passare il tipo di ritorno di Arrays.List al costruttore di ArrayList, qualcosa di simile (cioè pubblica ArrayList (Collection c).) -

List<String> girlFriends = new java.util.ArrayList<String>(Arrays.asList("Rose", "Leena", "Kim", "Tina")); 
girlFriends.add("Sarah"); 

Ora si può facilmente aggiungere alla vostra lista Sarah GF utilizzando lo stesso sintassi.

PS: selezionare questa o l'altra come risposta perché tutto è stato spiegato. Il tuo basso tasso di accettazione è molto scoraggiante.

Problemi correlati