Perché java.util.ArrayList consente di aggiungere null?

41

Mi chiedo perché java.util.ArrayList consente di aggiungere null . C'è qualche caso in cui vorrei aggiungere null a un ArrayList ?

Sto facendo questa domanda perché in un progetto abbiamo riscontrato un bug in cui alcuni codici aggiungevano null a ArrayList ed era difficile individuare dove si trovasse il bug. Ovviamente è stato lanciato un NullPointerException , ma non prima che altro codice provasse ad accedere all'elemento. Il problema era come individuare il codice che ha aggiunto l'oggetto null . Sarebbe stato più semplice se ArrayList avesse lanciato un'eccezione nel codice in cui gli elementi venivano aggiunti.

    
posta Alfredo Osorio 03.09.2012 - 16:30
fonte

7 risposte

38

Questa decisione di progettazione sembra guidata principalmente dalla denominazione.

Nome ArrayList suggerisce di leggere una funzionalità simile a array - ed è naturale per Java Collections Framework i progettisti si aspettano che la stragrande maggioranza degli utenti API si baserà su di essa che funziona in modo simile agli array.

Questo in particolare riguarda il trattamento di elementi nulli. Utente API sapendo che sotto funziona OK:

array[0] = null; // NPE won't happen here

sarebbe piuttosto sorpreso per scoprire se codice simile per ArrayList getterebbe NPE:

arrayList.set(0, null); // NPE => WTF?

Il ragionamento come sopra è presentato in Esercitazione JCF sottolinea i punti che suggeriscono una stretta somiglianza tra ArrayList e array semplici:

ArrayList... offers constant-time positional access and is just plain fast...

Se vuoi che un'implementazione di List non consenta nulla, sarebbe meglio chiamarla come NonNullableArrayList o qualcosa del genere, per evitare di confondere gli utenti API.

Nota a margine c'è una discussione ausiliaria nei commenti qui sotto, insieme a considerazioni aggiuntive che supportano il ragionamento qui esposto.

    
risposta data 03.09.2012 - 17:01
fonte
30

Null potrebbe essere un valore valido per un elemento di una lista. Supponiamo che l'elenco contenga elementi che rappresentano alcuni dati opzionali relativi a un elenco di utenti e che siano archiviati nello stesso ordine degli utenti. Se i dati extra vengono popolati, l'elenco conterrà i dati aggiuntivi, altrimenti lo spazio corrispondente a un utente sarà nullo. (Sono sicuro che ci sono esempi migliori, ma ti viene l'idea)

se non vuoi consentire l'aggiunta di null, puoi avvolgere l'elenco di array con il tuo wrapper che ha gettato quando è stato aggiunto il valore nullo.

    
risposta data 03.09.2012 - 16:43
fonte
16

ArrayList consente null dalla progettazione. È intenzionale. Da javadoc :

"[ArrayList is a] resizable-array implementation of the List interface. Implements all optional list operations, and permits all elements, including null."

La risposta a "perché" è che se non fosse la ArrayList non sarebbe utilizzabile nei casi in cui è necessario inserire un null nella lista. Al contrario, è possibile impedire a un ArrayList di contenere valori null testando i valori prima di aggiungerli o utilizzando un wrapper che impedisca che ciò accada.

Is there any case where I would want to add null to an ArrayList?

Ovviamente, ogni caso in cui null ha un significato distinto. Ad esempio potrebbe significare che il valore in una determinata posizione nell'elenco non è stato inizializzato o fornito.

It would have been easier if the ArrayList had thrown an exception in the code where the elements was being added.

Potresti facilmente implementare questo comportamento creando una classe wrapper. Tuttavia, questo non è il comportamento che più programmatori / applicazioni richiedono.

    
risposta data 03.09.2012 - 16:50
fonte
8

C'è qualche caso in cui vorrei aggiungere null a un ArrayList?

Certo, per quanto riguarda la pre-assegnazione? Vuoi una ArrayList di cose che non puoi ancora creare perché non hai abbastanza informazioni. Solo perché non riesci a pensare a una ragione per cui qualcuno possa voler fare qualcosa non ne fa una cattiva idea. Qualunque cosa. (Ora, sono sicuro che qualcuno arriverà e dirà che dovresti invece avere oggetti vuoti che soddisfano qualche schema su un blog oscuro e che i programmatori dovrebbero davvero essere in grado di scrivere programmi senza mai usare if dichiarazioni, blah blah .)

Se voi ragazzi avete un contratto che non ci dovrebbe mai essere null s in un contenitore, dipende da voi per assicurarsi che il contratto sia rispettato, probabilmente in modo più appropriato affermando. Probabilmente ti avrebbe richiesto un massimo di 10 righe di codice. Java rende incredibilmente facile per te fare questo genere di cose. Il JDK non può leggerti nella mente.

    
risposta data 03.09.2012 - 18:11
fonte
4

Questa sembra essere più una questione filosofica (software-) qui.

ArrayList in quanto una classe di utilità è progettata per essere utile in un ampio contesto di possibili casi d'uso.

Contrariamente alla tua richiesta nascosta che l'accettazione di null come valore valido dovrebbe essere scoraggiata, ci sono molti esempi in cui il valore nullo è perfettamente legale.

Il singolo motivo più importante è che null è l'equivalente di do not know di qualsiasi tipo di riferimento, inclusi i tipi di framework. Ciò implica che null non può essere sostituito in ogni caso da una versione più fluente del valore nothing .

Quindi, diciamo che memorizzi gli Integers 1, 3, 7 nel tuo arraylist al suo indice corrispondente: A causa di alcuni calcoli, vuoi ottenere l'elemento all'indice 5, quindi quale array dovrebbe restituire è: "nessun valore memorizzato". Questo potrebbe essere ottenuto restituendo null oppure un NullObject . Nella maggior parte dei casi la restituzione del valore nullo incorporato è espressiva abbastanza. Dopo aver chiamato un metodo che può restituire null e utilizzando il suo valore di ritorno, un controllo del valore restituito rispetto a null è abbastanza comune nel codice moderno.

    
risposta data 16.07.2014 - 13:01
fonte
3

L'affermazione

File f = null;

è valido e utile (non credo di dover spiegare perché). È ugualmente utile avere una collezione di file, alcuni dei quali potrebbero essere nulli.

List<File> files = new ArrayList<File>();
// use my collection of files
// ....
// not using this one anymore:
files.set(3, null);

L'utilità delle raccolte che possono contenere oggetti nulli procede direttamente dall'utilità di oggetti che possono essere nulli. È davvero così semplice.

    
risposta data 09.10.2014 - 02:08
fonte
2

È più facile accettare tutto, piuttosto che essere restrittivo e quindi provare ad aprire il tuo progetto dopo il fatto.

Ad esempio, cosa succede se oracle / sun ha fornito solo NonNullableArrayList, ma si desidera poter aggiungere un null alla lista. Come lo faresti? Probabilmente dovresti creare un oggetto completamente diverso, non puoi usare estendere NonNullableArrayList. Invece se hai un ArrayList che prende tutto, puoi facilmente estenderlo, e sovrascrivere l'add, dove non accetta valori nulli.

    
risposta data 03.09.2012 - 17:45
fonte

Leggi altre domande sui tag