Pourquoi utiliser Optional.of plutôt que Optional.ofNullable?

232

Lorsque vous utilisez la Optionalclasse Java 8 , il existe deux façons dont une valeur peut être encapsulée dans une option.

String foobar = <value or null>;
Optional.of(foobar);         // May throw NullPointerException
Optional.ofNullable(foobar); // Safe from NullPointerException

Je comprends que Optional.ofNullablec'est le seul moyen sûr d'utiliser Optional, mais pourquoi Optional.ofexiste- t- il? Pourquoi ne pas simplement utiliser Optional.ofNullable et être en sécurité en tout temps?

tourbillon
la source
1
veuillez me dire quel package doit importer pour l'utiliser?
LoveToCode
4
@LoveToCode java.util.Optional- Il est disponible si vous utilisez JDK 8 ou version ultérieure
whirlwin
11
J'aimerais qu'ils aient ofNullable()nommé of()et of()nomméofNotNull()
Robert Niestroj
Veuillez consulter baeldung.com/java-optional
Sumesh TG
Comme vous demandez "pourquoi le fichier Optional.of existe-t-il? Pourquoi ne pas simplement utiliser le fichier Optional.ofNullable et être en sécurité à tout moment?" Disons que si les données requises par l'utilisateur ne sont pas présentes, nous devons lever l'exception. Cela dépend donc totalement de votre cas d'utilisation. baeldung.com/java-optional-throw-exception
Karan Arora

Réponses:

306

Votre question est basée sur l'hypothèse que le code qui peut être lancé NullPointerExceptionest pire que le code qui ne l'est pas. Cette hypothèse est fausse. Si vous vous attendez à ce que votre foobarne soit jamais nul en raison de la logique du programme, il est préférable de l'utiliser Optional.of(foobar)car vous verrez un NullPointerExceptionqui indiquera que votre programme a un bogue. Si vous utilisez Optional.ofNullable(foobar)et que foobarcela est nulldû au bogue, votre programme continuera silencieusement à fonctionner incorrectement, ce qui peut être un plus gros désastre. De cette façon, une erreur peut se produire beaucoup plus tard et il serait beaucoup plus difficile de comprendre à quel moment elle a mal tourné.

Tagir Valeev
la source
129
" Si vous vous attendez à ce que votre foobar ne soit jamais nulle en raison de la logique du programme, il est préférable de l'utiliserOptional.of(foobar) ". Cela semble un peu étrange - quand nous savons que la valeur ne sera nullen aucun cas, alors pourquoi ne pas utiliser la valeur elle-même, au lieu de l'envelopper dans un Optional?
Konstantin Yovkov
54
@kocko, vous devrez peut-être renvoyer la Optionalde la méthode comme requis par l'interface que vous implémentez (probablement d'autres implémenteurs peuvent retourner une option vide). Ou vous souhaitez créer une collection / flux d'options, dont certains sont garantis non nuls et d'autres non. Ou vous avez une logique conditionnelle qui crée une option dans plusieurs branches et dans une seule branche, vous êtes sûr qu'elle n'est pas nulle.
Tagir Valeev
28
Parce que Facultatif signifie qu'il peut être présent ou absent. Absent! = Null. nulldans ce cas signifie "Je m'attends à ce que foobar soit présent, mais à cause d'un bug, il est nul". Optional.isPresent() == falsesignifie que foobar n'est pas présent, c'est-à-dire qu'il s'agit d'un comportement légitime attendu.
Buurman
43
@kocko: exemple simple: return list.isEmpty()? Optional.empty(): Optional.of(list.get(0));le listne devrait jamais contenir de nullvaleurs…
Holger
5
@Harish si vous me demandez, je ne conseille pas d'utiliser les options partout. C'est une question distincte. Vous pouvez consulter quelques opinions ici .
Tagir Valeev
12

De plus, si vous savez que votre code ne devrait pas fonctionner si l'objet est nul, vous pouvez lever l'exception en utilisant Optional.orElseThrow

String nullName = null;
String name = Optional.ofNullable(nullName).orElseThrow(NullPointerException::new);
Karan Arora
la source
1
Mais pour cela, vous pouvez utiliser le plus court encoreString name = Objects.requireNonNull(nullName);
Holger
1
Bon point @Holger, cependant. La méthode .orElse () permet des exceptions personnalisées qui pourraient vous aider à mieux gérer le flux de contrôle ou la journalisation des informations.
Nikos Stais
1
Eh bien, vous pouvez fournir un message pour l'exception afin de fournir des informations supplémentaires. Toute autre tentative de personnalisation, comme l'utilisation d'une exception différente que NullPointerExceptionlorsque le problème est clairement une référence nullalors qu'il ne devrait pas, serait un pas dans la mauvaise direction.
Holger
vous pouvez également utiliser Facultatif pour lancer une exception plus spécifique (par exemple personnalisée), pas NPE, NPE est trop générique, vous pouvez lancer quelque chose commenew NullNameException("meaningful msg")
Dáve
1

Cela dépend des scénarios.

Supposons que vous ayez des fonctionnalités métier et que vous ayez besoin de traiter quelque chose avec cette valeur, mais que la nullvaleur au moment du traitement ait un impact.

Ensuite, dans ce cas, vous pouvez utiliser Optional<?>.

String nullName = null;

String name = Optional.ofNullable(nullName)
                      .map(<doSomething>)
                      .orElse("Default value in case of null");
Gautam Chaurasia
la source
0

Facultatif doit être utilisé principalement pour les résultats des services de toute façon. Dans le service, vous savez ce que vous avez sous la main et retournez Optional.of (someValue) si vous avez un résultat et retournez Optional.empty () si vous n'en avez pas. Dans ce cas, une valeur ne doit jamais être nulle et quand même, vous retournez un Facultatif.

espendennis
la source
1
Merci pour la modification de Sumesh, mais le "someValue" dans la dernière ligne que vous avez modifiée pour être "some Value", fait référence à la variable dans "Optional.of (someValue)" ci-dessus et devrait rester someValue, je pense.
espendennis