web-dev-qa-db-fra.com

L'utilisation de Optional.ofNullable en remplacement de l'opérateur ternaire est-elle une bonne pratique?

Considérez l'utilisation de cette expression:

String hi = Optional.ofNullable(sayHi()).orElse("-");

qui correspond effectivement à cette expression ternaire:

String hi = sayHi() != null ? sayHi() : "-";

Cette utilisation de Optional.ofNullable avec une méthode est-elle une bonne pratique? Ou simplement du codage extra-verbeux?


Je reconnais que Optional.ofNullable crée une variable et évite d’appeler deux fois la méthode sayHi(). Pour éviter ce problème, vous pourriez créer une variable supplémentaire, mais cela ajoute à la verbosité de l'option ternaire:

String hi = sayHi();
hi = hi != null ? hi : "-";

D'autre part, Optional.ofNullable crée dans le cas où hi n'est pas null un objet Optional supplémentaire. Il y a donc certainement plus de frais généraux.

Il semble donc y avoir des avantages et des inconvénients à utiliser ce type de construction pour remplacer le constructeur ternaire.


À propos: voici l'implémentation de Optional.ofNullable par Java 8:

public static <T> Optional<T> ofNullable(T value) {
    return value == null ? empty() : of(value);
}
7
gil.fernandes

Chaque fois que je pense à utiliser l’API facultative dans un but spécifique, je me rappelle toujours ce qu’elle était destinée à faire et pourquoi elle a été intégrée au JDK et c’est-à-dire 

Facultatif dans destiné à fournir un mécanisme limité pour la méthode de bibliothèque renvoyer les types où il est clairement nécessaire de représenter «pas de résultat» et où l'utilisation de null pour cela est extrêmement susceptible de provoquer des erreurs - Stuart Marks 

Facultatif est principalement axé sur un type de retour pouvant ou non avoir une valeur de retour. 

L'utilisation de cette construction, comme dans cet exemple spécifique, entraîne simplement une allocation de mémoire supplémentaire et une surcharge de la GC.

Je garderais les choses simples et ferais plutôt:

String hi = sayHi();
if(hi == null) hi = “-“;
...
11
Aomine

Dans JDK 9 ou version ultérieure, utilisez ceci:

String hi = Objects.requireNonNullElse(sayHi(), "-");

Cela évite de devoir répéter sayHi() si un opérateur ternaire est utilisé ou d'affecter sa valeur à une variable locale qui est réutilisée dans le ternaire. Ce pourrait être une petite amélioration. Cela évite également la question d'utiliser ou non Optional. :-)

9
Stuart Marks

Cette utilisation de Optional.ofNullable avec une méthode est-elle une bonne pratique?

Conceptuellement , c'est une mauvaise pratique. L'idée de base est de représenter l'absence d'une valeur de retour, pas d'envelopper tout ce qui pourrait être null. Je suis fermement contre cet usage.

Ou simplement du codage extra-verbeux?

Cela me semble être une tentative infructueuse de rendre votre code plus à la mode. ("Regardez, nous utilisons la toute nouvelle Optional de Java 8!") 

Je préfère la lisibilité et la clarté à la concision.

Cette utilisation de Optinal n'apporte pas de clarté, mais soulève des questions:

Pourquoi enroulez-vous la variable?
Qu'allez-vous faire avec cette Optional?
Sera-t-il utilisé/retourné ci-dessous?
 

Cela ne donne pas non plus de brièveté: votre deuxième ligne est encore plus courte.

Pour éviter ce problème, vous pouvez créer une variable supplémentaire, mais cela ajoute à la verbosité de l'option ternaire.

Vous ne créez pas une variable supplémentaire. La version d'une ligne pourrait être:

String hi = (hi = sayHi()) != null ? hi : "-";

Bien que votre suggestion de deux lignes est absolument bonne:

String messageContent = sayHi();
String hi = messageContent != null ? messageContent : "-";
6
Andrew Tobilko

Si vous autorisez Optional dans votre flux de travail, vous devriez envisager de modifier la méthode sayHi() afin qu'elle renvoie Optional<String>, ce qui rendra le résultat plus élégant:

hi = sayHi().orElse("-");

Si vous ne souhaitez pas introduire Optional dans votre flux de travail (car il crée un objet supplémentaire contenant la valeur facultative), il est préférable de vous en tenir aux simples contrôles NULL et à l'opérateur ternaire.

En ce qui concerne les coûts de performance de Optional (tels que l’augmentation du ramassage des ordures), vous devez profiler votre application et décider s’il s’agit ou non d’une préoccupation réelle.

De plus, si vous êtes surtout intéressé par String, sachez que la méthode Objects.toString(Object, String) renvoie une valeur par défaut si l'objet est null:

hi = Objects.toString(hi, "-");

C’est plus ordonné et plus élégant que d’écrire le code manuellement.

5
Bobulous

En résumé: évitez le type Optional ..... Le principal argument de Optional sur les types de retour est "Il est trop facile pour les clients d’oublier de gérer la possibilité d’une valeur de retour NULL. Optional est moche et à la figure, donc un client est moins susceptible d’oublier de gérer la possibilité d’une valeur de retour vide. Partout ailleurs, les programmeurs devraient continuer à utiliser des références normales, qui peuvent être nulles. " 

J'ai écrit une discussion sur les avantages et les inconvénients de l'utilisation du type Optional de Java: Rien n'est meilleur que le type facultatif .

0
mernst

Je pense que c'est surtout une question de goût personnel.

De mon point de vue, il serait plus judicieux de simplement renvoyer un Optional<String> et de laisser l’appelant s’occuper d’une valeur manquante.

Optionnel, étant un type monadique, peut être utilisé pour obtenir plus que simplement obtenir une valeur alt.

De l’autre côté, votre opérateur semble assez concis, s’il était utilisé systématiquement, il pourrait être pratique.

Je ne pense pas que la performance soit un gros problème ici.

0
minus