Plusieurs fois, je me retrouve à vérifier null lors de la récupération d'une valeur dans une hiérarchie de données pour éviter les NullPointerExceptions, que je trouve sujettes à des erreurs et qui nécessitent beaucoup de passe-partout.
J'ai écrit une routine très simple qui me permet d'ignorer la vérification nulle lors de la récupération d'un objet ...
public final class NoNPE {
public static <T> T get(NoNPEInterface<T> in) {
try {
return in.get();
} catch (NullPointerException e) {
return null;
}
}
public interface NoNPEInterface<T> {
T get();
}
}
Je l'utilise un peu comme ça ...
Room room = NoNPE.get(() -> country.getTown().getHouses().get(0).getLivingRoom());
Ce qui précède m'a permis d'obtenir un objet Room ou un null, sans avoir à vérifier tous les niveaux parent.
Que pensez-vous de ce qui précède? Suis-je en train de créer un motif problématique? Y a-t-il une meilleure façon de procéder à votre avis?
Votre solution est très intelligente. Le problème que je vois est le fait que vous ne savez pas pourquoi vous avez obtenu un null
? Est-ce parce que la maison n'avait pas de pièces? Était-ce parce que la ville n'avait pas de maisons? Est-ce parce que le pays n'a pas de villes? Était-ce parce qu'il y avait un null
dans la position 0 de la collection à cause d'une erreur même quand il y a des maisons dans les positions 1 et plus?
Si vous faites un usage extensif de la classe NonPE
, vous aurez de sérieux problèmes de débogage. Je pense qu'il vaut mieux savoir où exactement la chaîne est rompue que d'obtenir silencieusement un null
qui pourrait cacher une erreur plus profonde.
Cela viole également la loi de Déméter : country.getTown().getHouses().get(0).getLivingRoom()
. Plus souvent qu'autrement, la violation d'un bon principe vous oblige à mettre en œuvre des solutions peu orthodoxes pour résoudre le problème causé par la violation de ce principe.
Ma recommandation est que vous l'utilisiez avec prudence et essayez de résoudre le défaut de conception qui vous oblige à encourir dans le train wreck antipattern (donc vous n'avez pas à utiliser NonPE
partout) . Sinon, vous pourriez avoir des bogues difficiles à détecter.
L'idée est bonne, vraiment bonne en fait. Étant donné que Java 8 les types Optional
existent, une explication détaillée peut être trouvée à type Java facultatif . Un exemple avec ce que vous avez publié est
Optional.ofNullable(country)
.map(Country::getTown)
.map(Town::Houses);
Et plus loin.
Je peux ressentir votre douleur, mais la solution proposée est une mauvaise idée.
NoNPE.get
.Optional.map
est ce que vous recherchez.En remarque, NoNPEInterface
est un doublon de Java.util.function.Supplier
.
Dans certains cas, vous pourriez envisager d'utiliser une expression d'évaluation utils qui sont présents dans de nombreux cadres (par exemple: EL, SpEL):
evaluateProperty(country, "town.houses[0].livingRoom")
Votre méthode fonctionne assez bien pour son objectif, bien que renvoyer null
s lorsque vous obtenez un NullPointerException
semble être une mauvaise conception.
Essayez d'éviter les null
s lorsque vous le pouvez et ne les passez que lorsqu'ils représentent quelque chose ou ont une signification spéciale et ne les renvoyez que lorsqu'ils représentent/signifient quelque chose - sinon vous devriez lancer un NullPointerException
. Cela évite les bugs et la confusion. Si un Object
ne doit pas être null
, un NullPointer
doit être jeté. Si un objet peut être null
, alors rien ne se passera mal lorsqu'il est passé. Sinon, votre méthode ci-dessus fonctionne.