J'ai un morceau de code comme celui-ci:
var fieldVal = getObject() .map(obj -> obj.getNullableField()) .orElseThrow(() -> new IllegalStateException("Object not found!")); return Optional.ofNullable(fieldVal) .orElseThrow(() -> new IllegalStateException("Field is not present"));
Pour le moment, je lance une exception lorsque l ' objet
donné n'est pas présent. p >
Maintenant, je dois également vérifier si le nullableField
de Object
est présent.
Une solution évidente pourrait être quelque chose comme ceci: p>
return getObject() .map(obj -> obj.getNullableField()) .orElseThrow(() -> new IllegalStateException("Object not found!"));
Mais j'aimerais l'implémenter dans la même chaîne fonctionnelle ...
Que me manque-t-il?
3 Réponses :
Il pourrait être implémenté directement dans la même chaîne, vous obtiendriez une exception différente. Maintenant, elle est moins lisible que votre première solution, bien sûr, vous avez donc un compromis.
return getObject().map(obj -> Optional.ofNullable(obj.getNullableField()) .orElseThrow(() -> new IllegalStateException("Field is not present"))) .orElseThrow(() -> new IllegalStateException("Object not found!"));
Je recommanderais de ne pas imbriquer (et généralement d'utiliser) des options, la lisibilité est abattue, mais bonne réponse quand même;)
@Lino En effet, c'est pourquoi je l'ai mis aussi comme deuxième phrase. Je recommanderais une séparation claire entre l'invocation et l'assignation, ce qui crée un code plus maintenable.
Plutôt que d'imbriquer, je suggérerais une séquence simple pour résoudre cela comme:
var value = getObject() .orElseThrow(() -> new IllegalStateException("Object not found!")); return Optional.of(value) // ensured value check already .map(CustomObject::getNullableField) // takes care ofNullable .orElseThrow(() -> new IllegalStateException("Field is not present"));
Cela corrige le code en question qui lèverait toujours IllegalStateException ("Object not found!")
même si l'attribut dans l'objet est null
et assure une vérification séquentielle pour aller plus loin en termes d'attributs d'entités.
Je recommanderais d'abandonner complètement l'approche Facultatif
ou du moins de ne l'utiliser qu'au début (en imaginant que getObject ()
ne peut pas être modifié):
var value = getObject() .orElseThrow(() -> new IllegalStateException("Object not found!")); var field = value.getNullableField(); if(field == null) { throw new IllegalStateException("Field is not present"); } return field;
Cela n'introduit pas de nouveau wrapper facultatif
juste pour que vous puissiez être "fluide" et tout faire en une seule ligne / instruction.
Avez-vous besoin de deux messages d'erreur différents?
@ OleV.V.oui je fais
@davioooh Juste une note, votre code actuel ne lèvera qu'une seule exception
nouvelle IllegalStateException ("Object not found!")
. Même si l'objet n'est pas nul mais que l'attribut qu'il contient est nul.@nullpointer oui, vous avez raison!