6
votes

Chaînage facultatif. OuElseThrow

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?


4 commentaires

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!


3 Réponses :


8
votes

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!"));


2 commentaires

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.



4
votes

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"));


1 commentaires

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.



0
votes

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.


0 commentaires