Utilisations pour facultatif

271

Après avoir utilisé Java 8 depuis plus de 6 mois environ, je suis assez satisfait des nouvelles modifications de l'API. Un domaine auquel je ne suis toujours pas confiant est le moment de l'utiliser Optional. Je semble osciller entre vouloir l'utiliser partout où quelque chose peut être null, et nulle part du tout.

Il semble y avoir beaucoup de situations où je pourrais l'utiliser, et je ne suis jamais sûr s'il ajoute des avantages (lisibilité / sécurité nulle) ou s'il provoque simplement des frais supplémentaires.

Donc, j'ai quelques exemples, et je serais intéressé par les réflexions de la communauté pour savoir si Optionalc'est bénéfique.

1 - En tant que type de retour de méthode publique lorsque la méthode peut retourner null:

public Optional<Foo> findFoo(String id);

2 - Comme paramètre de méthode lorsque le paramètre peut être null:

public Foo doSomething(String id, Optional<Bar> barOptional);

3 - En tant que membre facultatif d'un bean:

public class Book {

  private List<Pages> pages;
  private Optional<Index> index;

}

4 - Dans Collections:

En général, je ne pense pas:

List<Optional<Foo>>

ajoute quoi que ce soit - d'autant plus que l'on peut utiliser filter()pour supprimer des nullvaleurs, etc., mais y a-t-il de bonnes utilisations Optionaldans les collections?

Des cas que j'ai ratés?

Volonté
la source
2
Un cas que je trouve utile est, par exemple, si vous avez une carte de substitution. Par exemple Map<Character, String>. S'il n'y a pas de substitution je peux utiliser ceci: Optional.ofNullable(map.get(c)).orElse(String.valueOf(c)). Notez également que Facultatif a été volé à Guava et qu'il a une syntaxe beaucoup plus agréable:Optional.fromNullable(map.get(c)).or(String.valueOf(c));
fge
3
De plus, dans les collections, eh bien, il y a des collections qui n'autorisent pas les valeurs nulles! En option, la facture est ici. Et vous pouvez .filter(Optional::absent)sortir des "valeurs nulles"
fge
2
@fge En toute honnêteté, je pense que le concept d' Optional provient en fait de la PF.
VH-NZZ
2
@fge n'est-ce pas mieux exprimé avec getOrDefault()?
Jim Garrison

Réponses:

206

Le point principal de Optionalest de fournir un moyen pour une fonction renvoyant une valeur pour indiquer l'absence d'une valeur de retour. Voir cette discussion . Cela permet à l'appelant de continuer une chaîne d'appels de méthode fluide.

Cela correspond le plus étroitement au cas d'utilisation n ° 1 de la question du PO. Cependant, l' absence de valeur est une formulation plus précise que null car quelque chose comme IntStream.findFirstcela ne pourrait jamais retourner null.

Pour le cas d'utilisation # 2 , en passant un argument facultatif à une méthode, cela pourrait fonctionner, mais c'est plutôt maladroit. Supposons que vous ayez une méthode qui accepte une chaîne suivie d'une deuxième chaîne facultative. Accepter un Optionalcomme deuxième argument entraînerait un code comme celui-ci:

foo("bar", Optional.of("baz"));
foo("bar", Optional.empty());

Même accepter null est plus agréable:

foo("bar", "baz");
foo("bar", null);

Le mieux est probablement d'avoir une méthode surchargée qui accepte un seul argument de chaîne et fournit une valeur par défaut pour le second:

foo("bar", "baz");
foo("bar");

Cela a des limites, mais c'est beaucoup plus agréable que ce qui précède.

Les cas d'utilisation # 3 et # 4 , ayant un Optionaldans un champ de classe ou dans une structure de données, sont considérés comme une mauvaise utilisation de l'API. Tout d'abord, cela va à l'encontre de l'objectif principal de conception, Optionalcomme indiqué en haut. Deuxièmement, cela n'ajoute aucune valeur.

Il existe trois façons de gérer l'absence d'une valeur dans un Optional: pour fournir une valeur de remplacement, pour appeler une fonction pour fournir une valeur de remplacement ou pour lever une exception. Si vous stockez dans un champ, vous le feriez au moment de l'initialisation ou de l'affectation. Si vous ajoutez des valeurs dans une liste, comme l'OP l'a mentionné, vous avez le choix supplémentaire de simplement ne pas ajouter la valeur, "aplatissant" ainsi les valeurs absentes.

Je suis sûr que quelqu'un pourrait trouver des cas artificiels où il veut vraiment stocker un Optionaldans un champ ou une collection, mais en général, il vaut mieux éviter de le faire.

Stuart Marks
la source
47
Je suis en désaccord avec # 3. Il peut être utile d'avoir Optionalun champ en tant que lorsque des choses doivent être faites ou ne pas être faites en présence ou en l'absence d'une valeur.
glglgl
15
Je ne vois pas pourquoi faire en if(foo == null)interne serait mieux que simplement stocker le terrain en tant que optional. Et je ne vois pas pourquoi appeler explicitement en getOptionalFoo()interne est mieux que simplement stocker le champ en tant que Optional. De plus, si un champ peut être nullet un champ ne peut pas l'être null, pourquoi ne pas le communiquer au compilateur en les créant Optionalou non Optional.
mogronalol
27
@StuartMarks, c'est l'une des choses qui me déconcerte quand j'entends tous les Optional<>experts: "ne pas stocker Optional<>dans un champ". J'essaie vraiment de comprendre le point de cette recommandation. Considérons un arbre DOM où un nœud pourrait avoir un parent ou non. Il semble que dans le cas d'utilisation qui Node.getParent()reviendrait Optional<Node>. Suis-je vraiment censé stocker nullet envelopper le résultat à chaque fois? Pourquoi? Qu'est-ce que cette inefficacité supplémentaire m'achète, à part rendre mon code laid?
Garret Wilson
7
@GarretWilson D'un autre côté, supposez que vous l'ayez Optional<Node> getParent() { return Optional.ofNullable(parent); }. Cela semble cher car il alloue un à Optionalchaque fois! Mais si l'appelant le déballe immédiatement, l'objet est extrêmement éphémère et n'est jamais promu hors de l'espace Eden. Il pourrait même être éliminé par l'analyse d'échappement du JIT. La réponse Optionalfinale est "cela dépend" comme toujours, mais l'utilisation dans des champs peut potentiellement surcharger l'utilisation de la mémoire et ralentir la traversée de la structure des données. Et enfin, je pense que cela encombre le code, mais c'est une question de goût.
Stuart Marks
6
@GarretWilson Alors, vous avez écrit un blog pour ça? Cela m'intéresserait :)
akhil_mittal
78

Je suis en retard dans le jeu mais pour ce que ça vaut, je veux ajouter mes 2 cents. Ils vont à l'encontre de l' objectif de conception deOptional , qui est bien résumé par la réponse de Stuart Marks , mais je suis toujours convaincu de leur validité (évidemment).

Utiliser partout en option

En général

J'ai écrit un article de blogOptional complet sur l'utilisation, mais cela se résume à ceci:

  • concevez vos classes pour éviter le caractère optionnel dans la mesure du possible
  • dans tous les cas restants, la valeur par défaut devrait être d'utiliser Optionalau lieu denull
  • faire éventuellement des exceptions pour:
    • variables locales
    • renvoyer des valeurs et des arguments aux méthodes privées
    • blocs de code critiques pour les performances (pas de suppositions, utilisez un profileur)

Les deux premières exceptions peuvent réduire le surcoût perçu des références d'emballage et de déballage dans Optional. Ils sont choisis de telle sorte qu'un nul ne puisse jamais légalement passer une frontière d'une instance à une autre.

Notez que cela n'autorisera presque jamais Optionals dans les collections, ce qui est presque aussi mauvais que nulls. Ne le fais pas. ;)

Concernant vos questions

  1. Oui.
  2. Si la surcharge n'est pas une option, oui.
  3. Si d'autres approches (sous-classement, décoration, ...) ne sont pas envisageables, oui.
  4. Je t'en prie, non!

Les avantages

Cela réduit la présence de nulls dans votre base de code, mais ne les supprime pas. Mais ce n'est même pas le point principal. Il existe d'autres avantages importants:

Clarifie l'intention

L'utilisation Optionalexprime clairement que la variable est, eh bien, facultative. Tout lecteur de votre code ou consommateur de votre API sera battu au-dessus de la tête par le fait qu'il pourrait ne rien y avoir et qu'un contrôle est nécessaire avant d'accéder à la valeur.

Supprime l'incertitude

Sans Optionalle sens d'un nullévénement n'est pas clair. Il peut s'agir d'une représentation légale d'un état (voir Map.get) ou d'une erreur d'implémentation comme une initialisation manquante ou échouée.

Cela change radicalement avec l'utilisation persistante de Optional. Ici, déjà l'occurrence de nullsignifie la présence d'un bug. (Parce que si la valeur avait été manquante, un Optionalaurait été utilisé.) Cela rend le débogage d'une exception de pointeur nul beaucoup plus facile car la question de la signification de cela nullest déjà résolue.

Plus de contrôles nuls

Maintenant que rien ne peut nullplus être , cela peut être appliqué partout. Que ce soit avec des annotations, des assertions ou des vérifications simples, vous n'avez jamais à vous demander si cet argument ou ce type de retour peut être nul. Ça ne peut pas!

Désavantages

Bien sûr, il n'y a pas de solution miracle ...

Performance

L'encapsulation de valeurs (en particulier les primitives) dans une instance supplémentaire peut dégrader les performances. Dans les boucles serrées, cela peut devenir perceptible, voire pire.

Notez que le compilateur peut être en mesure de contourner la référence supplémentaire pour les durées de vie de courte durée de Optionals. En Java 10 , les types de valeurs peuvent réduire ou supprimer davantage la pénalité.

Sérialisation

Optionaln'est pas sérialisable mais une solution de contournement n'est pas trop compliquée.

Invariance

En raison de l'invariance des types génériques en Java, certaines opérations deviennent lourdes lorsque le type de valeur réel est poussé dans un argument de type générique. Un exemple est donné ici (voir "Polymorphisme paramétrique") .

Nicolai
la source
Un autre inconvénient (ou limitation) est que vous ne pouvez pas trier les instances facultatives (xxx), bien qu'Oracle ait clairement imposé cette restriction délibérément. Je suis sceptique quant à la sagesse d'avoir ces classes disponibles là où elles ne devraient être utilisées que dans des circonstances spécifiques, et en supposant que le développeur fera la bonne chose. La résolution d'un problème peut en entraîner un autre. Peut-être devrait-il y avoir des avertissements du compilateur pour aider le développeur lors de l'utilisation des classes Facultatif (xxx) de manière "indésirable" (par exemple en tant que paramètres de méthode, dans des collections, dans des constructeurs, etc.) si ce n'est vraiment pas l'usage prévu?
skomisa
À propos de 4, les options dans les collections: il est en fait parfois utile de stocker les options dans le Lists. C'est le cas lorsqu'il est important qu'un certain élément se trouve à un certain indice, mais que l'élément peut être présent ou non. Cela est clairement communiqué par un List<Optional<T>>type. Si d'un autre côté il est seulement important de savoir quels objets qui sont membres d'une certaine collection, alors il n'y a pas de point.
Lii
3
Je pense que le cas d'utilisation # 2 est toujours très discutable. Un Optionalêtre passé dans une méthode peut l'être null. Alors qu'avez-vous gagné? Vous avez maintenant deux contrôles à effectuer. Voir stackoverflow.com/a/31923042/650176
David V
2
@DavidV examine la liste des avantages que j'ai donnés - ils s'appliquent tous à ce cas également. D'ailleurs, si vous allez à fond Optional(ce qui devrait être le cas si vous êtes prêt à le passer comme arguments), cela nulln'a jamais de valeur légale. Donc, appeler une méthode avec un paramètre explicite nullest évidemment une erreur.
Nicolai
28

Personnellement, je préfère utiliser l'outil d'inspection de code d'IntelliJ pour l'utiliser @NotNullet les @Nullablevérifier car ce sont en grande partie du temps de compilation (peut avoir des vérifications d'exécution). Cela a une charge inférieure en termes de lisibilité du code et de performances d'exécution. Ce n'est pas aussi rigoureux que d'utiliser facultatif, mais ce manque de rigueur devrait être soutenu par des tests unitaires décents.

public @Nullable Foo findFoo(@NotNull String id);

public @NotNull Foo doSomething(@NotNull String id, @Nullable Bar barOptional);

public class Book {

  private List<Pages> pages;
  private @Nullable Index index;

}

List<@Nullable Foo> list = ..

Cela fonctionne avec Java 5 et pas besoin d'encapsuler et de dérouler les valeurs. (ou créez des objets wrapper)

Peter Lawrey
la source
7
Euh, ce sont des annotations IDEA? Je préfère personnellement le JSR 305 @Nonnull- fonctionne avec FindBugs;)
fge
@fge Il y a un manque de normes à cet égard, mais je pense que les outils sont généralement configurables et vous n'avez pas à vous retrouver avec@Nonnull @NotNull etc
Peter Lawrey
4
Oui c'est vrai; IDEA (13.x) donne trois choix différents ... Meh, je finis toujours par utiliser JSR 305 anywa
fge
3
Je sais que c'est vieux, mais la discussion sur les annotations et les outils mérite un lien vers stackoverflow.com/questions/35892063/… - qui en particulier aborde spécifiquement le cas de Java 8.
Stephan Herrmann
25

Je pense que le Guava Facultatif et leur page wiki le disent assez bien:

Outre l'augmentation de la lisibilité qui résulte du fait de donner un nom à null, le plus grand avantage d'Optional est sa résistance à l'idiot. Cela vous oblige à penser activement au cas absent si vous voulez que votre programme compile, car vous devez déballer activement l'option et traiter ce cas. Null, il est troublant facilement d'oublier simplement des choses, et bien que FindBugs aide, nous ne pensons pas qu'il résout presque aussi bien le problème.

Cela est particulièrement pertinent lorsque vous renvoyez des valeurs qui peuvent ou non être "présentes". Vous (et d'autres) sont beaucoup plus susceptibles d'oublier que other.method (a, b) pourrait renvoyer une valeur nulle que vous risquez d'oublier que a pourrait être nul lorsque vous implémentez other.method. Le retour facultatif empêche les appelants d'oublier ce cas, car ils doivent déballer l'objet eux-mêmes pour que leur code soit compilé. - (Source: Guava Wiki - Utiliser et éviter null - À quoi ça sert? )

Optionalajoute quelques frais généraux, mais je pense que son avantage clair est de rendre explicite qu'un objet pourrait être absent et il oblige les programmeurs à gérer la situation. Cela empêche que quelqu'un oublie le != nullchèque bien-aimé .

En prenant l'exemple de 2 , je pense qu'il est beaucoup plus explicite d'écrire du code:

if(soundcard.isPresent()){
  System.out.println(soundcard.get());
}

que

if(soundcard != null){
  System.out.println(soundcard);
}

Pour moi, le Optionalmeilleur capture le fait qu'il n'y a pas de carte son présente.

Mes 2 ¢ sur vos points:

  1. public Optional<Foo> findFoo(String id);- Je ne suis pas certain de cela. Peut-être que je retournerais un Result<Foo>qui pourrait être vide ou contenir un Foo. C'est un concept similaire, mais pas vraiment un Optional.
  2. public Foo doSomething(String id, Optional<Bar> barOptional);- Je préférerais @Nullable et une vérification des trouvailles, comme dans la réponse de Peter Lawrey - voir aussi cette discussion .
  3. Votre exemple de livre - je ne sais pas si j'utiliserais le Facultatif en interne, cela pourrait dépendre de la complexité. Pour l '"API" d'un livre, j'utiliserais un Optional<Index> getIndex()pour indiquer explicitement que le livre pourrait ne pas avoir d'index.
  4. Je ne l'utiliserais pas dans les collections, plutôt que de ne pas autoriser les valeurs nulles dans les collections

En général, j'essaierais de minimiser le contournement de l' nullart. (Une fois brûlé ...) Je pense qu'il vaut la peine de trouver les abstractions appropriées et d'indiquer aux autres programmeurs ce qu'une certaine valeur de retour représente réellement.

Behe
la source
15
Vous écririez soundcard.ifPresent(System.out::println). Appeler isPresentest sémantiquement la même chose que rechercher null.
un meilleur olivier du
Le problème pour moi est que les choses avec des types facultatifs peuvent toujours être nulles. Donc, pour être complètement sûr, vous devez faire quelque chose comme if(soundcard != null && soundcard.isPresent()). Bien que créer une API qui retourne un Facultatif et pourrait également retourner null est quelque chose que j'espère que personne ne fera jamais.
Simon Baumgardt-Wellander
"Cela vous oblige à penser activement au cas absent si vous voulez que votre programme compile du tout, car vous devez déballer activement l'option et traiter ce cas." Je ne sais pas vraiment comment cela force cela, bien que je ne travaille pas beaucoup en Java. Pourriez-vous expliquer ce que Java fait pour vous forcer à déballer ET vérifier le cas! IsPresent simplement pour compiler?
écraser
15

À partir du didacticiel Oracle :

Le but d'Optional n'est pas de remplacer chaque référence null unique dans votre base de code, mais plutôt d'aider à concevoir de meilleures API dans lesquelles, simplement en lisant la signature d'une méthode, les utilisateurs peuvent dire s'ils doivent s'attendre à une valeur facultative. De plus, Facultatif vous oblige à déballer activement un Facultatif pour faire face à l'absence de valeur; par conséquent, vous protégez votre code contre les exceptions de pointeur nul involontaires.

ctomek
la source
3
API juste pour la partie retour de la méthode, non? Les options ne doivent pas être utilisées comme paramètres en raison de l'effacement de type? Parfois, j'utilise un Facultatif en interne dans une méthode, converti à partir d'un paramètre nullable ou en tant que champ initialisé à partir d'un paramètre constructeur null ... essayant toujours de comprendre si cela est plus utile que de le laisser simplement nul - quelqu'un a des idées?
ycomp
@ycomp Vous pouvez trouver beaucoup d'informations sur ces cas dans telle ou telle question. Les réponses à ces questions en disent beaucoup plus que ce qui a été demandé et couvrent d'autres cas. Pour plus d'informations, parcourez davantage ou posez votre propre question, car vous n'obtiendrez probablement pas beaucoup d'attention ici. ; )
ctomek
8

1 - En tant que type de retour de méthode publique lorsque la méthode peut retourner null:

Voici un bon article qui montre l'utilité du cas d'utilisation # 1. Là ce code

...
if (user != null) {
    Address address = user.getAddress();
    if (address != null) {
        Country country = address.getCountry();
        if (country != null) {
            String isocode = country.getIsocode();
            isocode = isocode.toUpperCase();
        }
    }
}
...

se transforme en

String result = Optional.ofNullable(user)
  .flatMap(User::getAddress)
  .flatMap(Address::getCountry)
  .map(Country::getIsocode)
  .orElse("default");

en utilisant Facultatif comme valeur de retour des méthodes getter respectives .

artifex
la source
2

Voici une utilisation intéressante (je crois) pour ... les tests.

J'ai l'intention de tester fortement un de mes projets et je construis donc des assertions; il y a seulement des choses que je dois vérifier et d'autres non.

Je construis donc des choses à affirmer et j'utilise un assert pour les vérifier, comme ceci:

public final class NodeDescriptor<V>
{
    private final Optional<String> label;
    private final List<NodeDescriptor<V>> children;

    private NodeDescriptor(final Builder<V> builder)
    {
        label = Optional.fromNullable(builder.label);
        final ImmutableList.Builder<NodeDescriptor<V>> listBuilder
            = ImmutableList.builder();
        for (final Builder<V> element: builder.children)
            listBuilder.add(element.build());
        children = listBuilder.build();
    }

    public static <E> Builder<E> newBuilder()
    {
        return new Builder<E>();
    }

    public void verify(@Nonnull final Node<V> node)
    {
        final NodeAssert<V> nodeAssert = new NodeAssert<V>(node);
        nodeAssert.hasLabel(label);
    }

    public static final class Builder<V>
    {
        private String label;
        private final List<Builder<V>> children = Lists.newArrayList();

        private Builder()
        {
        }

        public Builder<V> withLabel(@Nonnull final String label)
        {
            this.label = Preconditions.checkNotNull(label);
            return this;
        }

        public Builder<V> withChildNode(@Nonnull final Builder<V> child)
        {
            Preconditions.checkNotNull(child);
            children.add(child);
            return this;
        }

        public NodeDescriptor<V> build()
        {
            return new NodeDescriptor<V>(this);
        }
    }
}

Dans la classe NodeAssert, je fais ceci:

public final class NodeAssert<V>
    extends AbstractAssert<NodeAssert<V>, Node<V>>
{
    NodeAssert(final Node<V> actual)
    {
        super(Preconditions.checkNotNull(actual), NodeAssert.class);
    }

    private NodeAssert<V> hasLabel(final String label)
    {
        final String thisLabel = actual.getLabel();
        assertThat(thisLabel).overridingErrorMessage(
            "node's label is null! I didn't expect it to be"
        ).isNotNull();
        assertThat(thisLabel).overridingErrorMessage(
            "node's label is not what was expected!\n"
            + "Expected: '%s'\nActual  : '%s'\n", label, thisLabel
        ).isEqualTo(label);
        return this;
    }

    NodeAssert<V> hasLabel(@Nonnull final Optional<String> label)
    {
        return label.isPresent() ? hasLabel(label.get()) : this;
    }
}

Ce qui signifie que l'assertion ne se déclenche vraiment que si je veux vérifier l'étiquette!

fge
la source
2

OptionalLa classe vous permet d'éviter d'utiliser nullet de fournir une meilleure alternative:

  • Cela encourage le développeur à vérifier la présence afin d'éviter les captures non détectées NullPointerException.

  • L'API est mieux documentée car il est possible de voir où s'attendre aux valeurs qui peuvent être absentes.

Optionalfournit une API pratique pour continuer à travailler avec l'objet isPresent():; get(); orElse(); orElseGet(); orElseThrow(); map(); filter(); flatmap().

De plus, de nombreux frameworks utilisent activement ce type de données et le renvoient de leur API.


la source
2

En java, ne les utilisez pas sauf si vous êtes accro à la programmation fonctionnelle.

Ils n'ont pas leur place en tant qu'arguments de méthode (je prémesserai quelqu'un un jour vous passera une option nulle nulle, pas seulement une option vide).

Ils ont un sens pour les valeurs de retour, mais ils invitent la classe cliente à continuer d'étirer la chaîne de développement du comportement.

FP et les chaînes ont peu de place dans un langage impératif comme java car il est très difficile à déboguer, pas seulement à lire. Lorsque vous passez à la ligne, vous ne pouvez pas connaître l'état ni l'intention du programme; vous devez intervenir pour le comprendre (dans du code qui n'est souvent pas le vôtre et de nombreux cadres de pile en profondeur malgré les filtres d'étape) et vous devez ajouter de nombreux points d'arrêt pour vous assurer qu'il peut s'arrêter dans le code / lambda que vous avez ajouté, au lieu de simplement parcourir les lignes triviales if / else / call.

Si vous voulez une programmation fonctionnelle, choisissez autre chose que Java et j'espère que vous avez les outils pour le déboguer.

user2023577
la source
1

Je ne pense pas que Facultatif soit un substitut général aux méthodes qui retournent potentiellement des valeurs nulles.

L'idée de base est: L'absence d'une valeur ne signifie pas qu'elle est potentiellement disponible à l'avenir. C'est une différence entre findById (-1) et findById (67).

La principale information des options pour l'appelant est qu'il peut ne pas compter sur la valeur donnée, mais qu'elle peut être disponible à un moment donné. Peut-être qu'il disparaîtra à nouveau et reviendra plus tard une fois de plus. C'est comme un interrupteur marche / arrêt. Vous avez la «possibilité» d'allumer ou d'éteindre la lumière. Mais vous n'avez aucune option si vous n'avez pas de lumière à allumer.

Je trouve donc trop compliqué d'introduire des options partout où précédemment null était potentiellement retourné. J'utiliserai toujours null, mais uniquement dans des zones restreintes comme la racine d'un arbre, l'initialisation paresseuse et les méthodes de recherche explicites.

oopexpert
la source
0

Semble Optionalest utile que si le type T en option est un type primitif comme int, long, char, etc. Pour les classes « réelles », il n'a pas de sens pour moi que vous pouvez utiliser une nullvaleur de toute façon.

Je pense qu'il a été pris d'ici (ou d'un autre concept de langage similaire).

Nullable<T>

En C #, cela a Nullable<T>été introduit il y a longtemps pour encapsuler les types de valeur.

peter.petrov
la source
2
C'est une arnaque de Guava Optionalen fait
fge
2
@fge OK mais quand c'était présent en C # (2005, MS.NET 2.0), il n'y avait pas de goyave, je pense. Et ... qui sait d'où C # a pris cela.
peter.petrov
3
@fge "Ripoff of Guava's Optional" est en quelque sorte une façon amusante de le dire, car les gars de la goyave ont participé aux discussions, ont fourni leurs expériences et étaient généralement en faveur de java.util.Optional.
Stuart Marks
6
@fge Sans aucun doute, les API Java ont été fortement influencées par celles de Guava. Je suis en désaccord avec "arnaque" qui sonne comme voler. Les gars de la goyave ont apporté de nombreuses idées précieuses à Java 8.
Stuart Marks
6
Vous manquez le point. Facultatif doit être utilisé au lieu de renvoyer null. Il est plus sûr que de lever potentiellement une NullPointerException. Voir: oracle.com/technetwork/articles/java/…
Kilizo
0

An a une sémantique similaire à une instance non modifiable du modèle de conception Iterator :Optional

  • il peut ou non faire référence à un objet (comme indiqué par isPresent())
  • il peut être déréférencé (en utilisant get()) s'il fait référence à un objet
  • mais il ne peut pas être avancé à la position suivante dans la séquence (il n'a pas de next()méthode).

Par conséquent, envisagez de renvoyer ou de passer un Optionaldans des contextes où vous auriez précédemment envisagé d'utiliser un Java Iterator.

Raedwald
la source
-1

Java SE 8 introduit une nouvelle classe appelée java.util.Optional,

Vous pouvez créer un Facultatif ou un Facultatif vide avec une valeur nulle.

Optional<String> emptyOptional = Optional.empty(); 

Et voici un Facultatif avec une valeur non nulle:

String valueString = new String("TEST");
Optional<String> optinalValueString = Optional.of(valueString );

Faites quelque chose si une valeur est présente

Maintenant que vous disposez d'un objet Facultatif, vous pouvez accéder aux méthodes disponibles pour traiter explicitement la présence ou l'absence de valeurs. Au lieu de devoir vous rappeler de faire une vérification nulle, comme suit:

String nullString = null;
if (nullString != null) {
    System.out.println(nullString);
}

Vous pouvez utiliser la méthode ifPresent (), comme suit:

Optional<String> optinalString= null;
optinalString.ifPresent(System.out::println);

package optinalTest;

import java.util.Optional;

public class OptionalTest {
    public Optional<String> getOptionalNullString() {
        return null;
//      return Optional.of("TESt");
    }

    public static void main(String[] args) {

        OptionalTest optionalTest = new OptionalTest();

        Optional<Optional<String>> optionalNullString = Optional.ofNullable(optionalTest.getOptionalNullString());

        if (optionalNullString.isPresent()) {
            System.out.println(optionalNullString.get());
        }
    }
}
Kumar Abhishek
la source
ce copypaste destiné à gagner une réputation bon marché, mais sans rapport avec les questions d'OP
stinger