Quel est le meilleur moyen de se protéger contre null dans une boucle for en Java?
Cela semble moche:
if (someList != null) {
for (Object object : someList) {
// do whatever
}
}
Ou
if (someList == null) {
return; // Or throw ex
}
for (Object object : someList) {
// do whatever
}
Il pourrait ne pas y avoir d'autre moyen. Devraient-ils l'avoir mis dans la construction for
elle-même, si elle est nulle alors ne lancez pas la boucle?
Vous devriez mieux vérifier d'où vous tirez cette liste.
Une liste vide est tout ce dont vous avez besoin, car une liste vide n'échouera pas.
Si vous obtenez cette liste ailleurs et que vous ne savez pas si c'est correct ou non, vous pouvez créer une méthode utilitaire et l'utiliser comme ceci:
for( Object o : safe( list ) ) {
// do whatever
}
Et bien sûr, safe
serait:
public static List safe( List other ) {
return other == null ? Collections.EMPTY_LIST : other;
}
Vous pourriez potentiellement écrire une méthode d'assistance qui renvoyait une séquence vide si vous passiez à null:
public static <T> Iterable<T> emptyIfNull(Iterable<T> iterable) {
return iterable == null ? Collections.<T>emptyList() : iterable;
}
Alors utilisez:
for (Object object : emptyIfNull(someList)) {
}
Je ne pense toutefois pas que je ferais cela - j’utiliserais généralement votre deuxième formulaire. En particulier, le "ou le lancer de l'ex" est important - s'il ne devrait pas être nul, vous devriez absolument lancer une exception. Vous savez que quelque chose a mal tourné, mais vous ne connaissez pas l'étendue des dégâts. Abandonner tôt.
Nous sommes déjà en 2017 et vous pouvez maintenant utiliser Apache Commons Collections4
L'usage:
for(Object obj : ListUtils.emptyIfNull(list1)){
// Do your stuff
}
Vous pouvez effectuer la même vérification null-safe pour les autres classes Collection avec CollectionUtils.emptyIfNull
.
Si vous obtenez cette List
à partir d'un appel de méthode que vous implémentez, ne renvoyez pas null
, renvoyez une List
vide.
Si vous ne pouvez pas modifier l'implémentation, alors vous êtes bloqué avec la vérification null
. Si cela ne devrait pas être null
, lancez une exception.
Je ne choisirais pas la méthode d'assistance qui renvoie une liste vide, car elle peut être utile à certains moments, mais vous vous habituez à l'appeler à chaque boucle que vous créez, masquant éventuellement des bogues.
Utilisez ArrayUtils.nullToEmpty
de la bibliothèque commons-lang
pour les tableaux
for( Object o : ArrayUtils.nullToEmpty(list) ) {
// do whatever
}
Cette fonctionnalité existe dans la bibliothèque commons-lang
, incluse dans la plupart des projets Java.
// ArrayUtils.nullToEmpty source code
public static Object[] nullToEmpty(final Object[] array) {
if (isEmpty(array)) {
return EMPTY_OBJECT_ARRAY;
}
return array;
}
// ArrayUtils.isEmpty source code
public static boolean isEmpty(final Object[] array) {
return array == null || array.length == 0;
}
C’est la même chose que la réponse donnée par @OscarRyz, mais dans l’intérêt du SEC mantra, je crois que cela vaut la peine de le noter. Voir la page commons-lang project. Voici la nullToEmpty
API documentation et source
Entrée Maven pour inclure commons-lang
dans votre projet s'il ne l'est pas déjà.
<dependency>
<groupId>org.Apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
Malheureusement, commons-lang
ne fournit pas cette fonctionnalité pour les types List
. Dans ce cas, vous devrez utiliser une méthode d'assistance, comme mentionné précédemment.
public static <E> List<E> nullToEmpty(List<E> list)
{
if(list == null || list.isEmpty())
{
return Collections.emptyList();
}
return list;
}
Avec Java 8 Optional
:
for (Object object : Optional.ofNullable(someList).orElse(Collections.emptyList())) {
// do whatever
}
J'ai modifié la réponse ci-dessus, vous n'avez donc pas besoin de lancer à partir d'un objet
public static <T> List<T> safeClient( List<T> other ) {
return other == null ? Collections.EMPTY_LIST : other;
}
puis appelez simplement la liste par
for (MyOwnObject ownObject : safeClient(someList)) {
// do whatever
}
Explication: MyOwnObject: Si List<Integer>
, alors MyOwnObject sera Integer dans ce cas.
Pour ceux qui ne souhaitent pas écrire leur propre méthode de sécurité statique null, vous pouvez utiliser: org.Apache.commons.lang.ObjectUtils.defaultIfNull(Object, Object)
de commons-lang Par exemple:
for (final String item :
(List<String>)ObjectUtils.defaultIfNull(items, Collections.emptyList())) { ... }
Une autre façon de se prémunir efficacement contre une valeur null dans une boucle for consiste à envelopper votre collection avec le code Optional<T>
de Google Guava, car elle permet, espère-t-on, de clarifier la possibilité d’une collection réellement vide, le client la collection est présente avec Optional.isPresent()
.
Utilisez la méthode CollectionUtils.isEmpty(Collection coll)
qui est Null-safe. Vérifiez si la collection spécifiée est vide.
pour ce import org.Apache.commons.collections.CollectionUtils
.
Dépendance Maven
<dependency>
<groupId>org.Apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.0</version>
</dependency>