web-dev-qa-db-fra.com

Pourquoi Java.util.ArrayList permet-il d'ajouter null?

Je me demande pourquoi Java.util.ArrayList permet d'ajouter null. Y a-t-il un cas où je voudrais ajouter null à un ArrayList?

Je pose cette question parce que dans un projet, nous avions un bug où du code ajoutait null au ArrayList et il était difficile de repérer où se trouvait le bug. De toute évidence, un NullPointerException a été lancé, mais pas tant qu'un autre code n'a pas essayé d'accéder à l'élément. Le problème était de savoir comment localiser le code qui a ajouté l'objet null. Cela aurait été plus facile si ArrayList avait jeté une exception dans le code où les éléments étaient ajoutés.

41
Alfredo Osorio

Cette décision de conception semble principalement motivée par la dénomination.

Name ArrayList suggère au lecteur une fonctionnalité similaire aux tableaux - et c'est naturel pour Java Collections Framework les concepteurs s'attendent à ce que la grande majorité des utilisateurs de l'API comptent sur un fonctionnement similaire aux tableaux.

Cela implique notamment le traitement des éléments nuls. L'utilisateur de l'API sachant que ci-dessous fonctionne bien:

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

serait assez surpris pour savoir si un code similaire pour ArrayList lancerait NPE:

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

Le raisonnement comme ci-dessus est présenté dans tutoriel JCF points de stress qui suggèrent une similitude étroite entre ArrayList et les tableaux simples:

ArrayList ... offre un accès positionnel à temps constant et est tout simplement rapide ...

Si vous souhaitez qu'une implémentation List interdise les valeurs nulles, il vaut mieux l'appeler comme NonNullableArrayList ou quelque chose comme ça, pour éviter de confondre les utilisateurs de l'API.


Note annexe il y a une discussion auxiliaire dans les commentaires ci-dessous, avec considérations supplémentaires soutenant le raisonnement présenté ici.

35
gnat

Null peut être une valeur valide pour un élément d'une liste. Supposons que votre liste contient des éléments qui représentent des données facultatives sur une liste d'utilisateurs et qu'elle est stockée dans le même ordre que les utilisateurs. Si les données supplémentaires sont renseignées, votre liste contiendra les données supplémentaires, sinon l'emplacement correspondant à un utilisateur sera nul. (Je suis sûr qu'il y a de meilleurs exemples, mais vous avez l'idée)

si vous ne voulez pas autoriser l'ajout de null, vous pouvez envelopper la liste de tableaux avec votre propre wrapper qui a été lancé lorsque null a été ajouté.

32
Sam Holder

ArrayList autorise null par conception. C'est intentionnel. De la javadoc :

"[ArrayList est une] implémentation d'un tableau redimensionnable de l'interface List. Implémente toutes les opérations de liste facultatives et autorise tous les éléments, y compris null ."

La réponse à "pourquoi" est que si ce n'était pas le cas, ArrayList ne serait pas utilisable dans les cas où il est nécessaire de mettre un null dans la liste. En revanche, vous pouvez empêcher une ArrayList de contenir des valeurs NULL en testant des valeurs avant de les ajouter ou en utilisant un wrapper qui empêche cela de se produire.

Y a-t-il un cas où je voudrais ajouter null à une liste de tableaux?

Évidemment, tout cas où null a une signification distincte. Par exemple, cela pourrait signifier que la valeur à une position donnée dans la liste n'a pas été initialisée ou fournie.

Il aurait été plus facile si ArrayList avait levé une exception dans le code où les éléments étaient ajoutés.

Vous pouvez facilement implémenter ce comportement en créant une classe wrapper. Cependant, ce n'est pas le comportement dont ont besoin la plupart programmeurs/applications.

19
Stephen C

Y a-t-il un cas où je voudrais ajouter null à une ArrayList?

Bien sûr, qu'en est-il de la pré-allocation? Vous voulez un ArrayList de choses que vous ne pouvez pas encore créer parce que vous n'avez pas assez d'informations. Ce n'est pas parce que vous ne pouvez pas penser à une raison pour laquelle quelqu'un peut vouloir faire quelque chose. Peu importe. (Maintenant, je suis sûr que quelqu'un viendra et dira que vous devriez plutôt avoir des objets vides qui remplissent un modèle qu'ils lisent sur un blog obscur et que les programmeurs devraient vraiment pouvoir écrire des programmes sans jamais utiliser les instructions if , bla bla.)

Si vous avez un contrat qui ne devrait jamais contenir nulls dans un conteneur, c'est à vous de vous assurer que ce contrat est respecté, probablement de manière plus appropriée en affirmant. Cela vous aurait probablement pris au maximum 10 lignes de code. Java rend incroyablement facile pour vous ce genre de chose. Le JDK ne peut pas lire dans votre esprit.

8
James

Cela semble être davantage une question philosophique (logicielle) ici.

ArrayList en tant que classe utilitaire est conçue pour être utile dans un large contexte de cas d'utilisation possibles.

Contrairement à votre affirmation cachée selon laquelle l'acceptation de null comme valeur valide doit être découragée, il existe de nombreux exemples où la valeur null est parfaitement légale.

La raison la plus importante est que null est le do not know équivalent de tout type de référence, y compris les types de framework. Cela implique que null ne peut en aucun cas être remplacé par une version plus fluide de la valeur nothing.

Supposons donc que vous stockiez les entiers 1, 3, 7 dans votre liste d'array à son index correspondant: En raison de certains calculs, vous voulez obtenir l'élément à l'index 5, donc ce que votre tableau devrait retourner est: "aucune valeur stockée". Cela pourrait être réalisé en retournant null ou un NullObject . Dans la plupart des cas, le retour de la valeur nulle intégrée est suffisamment expressif. Après avoir appelé une méthode qui peut retourner null et en utilisant sa valeur de retour, une vérification de la valeur retournée par rapport à null est assez courante dans le code moderne.

4
Mare Infinitus

La déclaration

File f = null;

est valide et utile (je ne pense pas avoir besoin d'expliquer pourquoi). Il est également utile d'avoir une collection de fichiers, dont certains peuvent être nuls.

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

L'utilité des collections qui peuvent contenir des objets nuls procède directement de l'utilité des objets qui peuvent être nuls. C'est vraiment aussi simple que ça.

4
x-code

Il est plus facile de tout accepter que d'être restrictif, puis d'essayer d'ouvrir votre design après coup.

Par exemple, que se passerait-il s'ils Oracle/Sun fournissaient uniquement NonNullableArrayList, mais que vous vouliez pouvoir ajouter un Null à votre liste. Comment feriez-vous? Vous auriez probablement à créer un objet entièrement différent, vous ne pourriez pas utiliser étendre le NonNullableArrayList. Au lieu de cela, si vous avez une liste de tableaux qui prend tout, vous pouvez facilement l'étendre et remplacer l'ajout, où il n'accepte pas les valeurs nulles.

2
NiteRain