Dans cet article


Offres d'emploi

Tags

Optional – JAVA 8 – la fin des NPE

Optional – JAVA 8 – la fin des NPE

La fonctionnalité de Optional pour éviter les NPE.

Un peu d’histoire sur le NPE:

JAVA avait comme idée originale de supprimer la notion de pointeur (du moins de la masquer) afin de faciliter la vie des développeurs. Néanmoins pour des raisons de simplicité, la « valeur » null a été laissé. Et « à cause » de cette valeur null, a été créé la fameuse exception NullPointerException qui est l’erreur à la fois la plus connue et la plus détestable car généralement on ne peut plus rien y faire…

Problème avec le NullPointerException:

  • C’est une source d’erreur : la NPE est de loin l’erreur la plus fréquente en Java.
  • La NPE oblige à rajouter énormément de code pour tester si une variable n’est pas null.
  • Ça n’apporte rien au niveau sémantique.
  • C’est contre la philosophie Java qui souhaite masquer la notion de pointeur.

Qu’est-ce qu’un optional?

Un optional est une classe qui « wrappe » l’objet dont on a réellement besoin. L’optional encapsule dont l’objet métier et indique directement que cet objet est « facultatif » c’est à dire qu’il peut être présent ou non.

Optional en JAVA

Optional en JAVA

Dans quel cas utiliser les Optional?

Le cas le plus évident est dans les classes métiers, celles qui portent les valeurs. Prenons un exemple d’une commande. Dans une commande, il existe un objet client qui stocke les informations du client. Mais lors du processus de commande, c’est objet client n’existe peut-être pas encore. Imaginons que nous soyons dans une commande web et que le client n’est pas encore loggué. Avant les optionals, il était donc nécessaire de tester la nullité de l’objet client dans la classe commande presque à chaque utilisation, ce qui est très pénible. De plus, un développeur qui reprend le classe commande plus loin dans l’application, n’a aucun moyen de savoir (hormis la documentation) si le client va être présent dans la classe Commande. Pour pallier à ce problème, l’utilisation de la classe Wrapper Optional répond à ce problème de la manière suivante:

Dans la classe Commande, au lieu de stocker l’objet Client, on stocke un Optional. Ceci indique directement que l’objet client peut être présent dans la classe ou peut être pas. L’avantage c’est qu’en terme de visibilité, il devient facile de le comprendre. Sémantiquement c’est un plus indiscutable.

Optional et utilisation

Premier exemple, ici on renseigne dans la classe commande un client qui est optional

public class Commande{
    private Optional<
Client> client = Optional.empty();
}

Il existe plusieurs manière de créer des optionals:

Optional<
DomainObject> opt = Optional.empty();
Optional<
DomainObject> opt = Optional.of(objet);
Optional<
DomainObject> opt = Optional.ofNullable(objet);

Pour récupérer la valeur, on peut utiliser la méthode map avec une référence de méthode. L’avantage des optionals, est l’utilisation des methodes orElse ou orElseGet. Méthode orElse(T) permet de créer un objet si l’objet n’existe pas, comme une valeur par défaut sur un String.

La méthode orElseGet(Supplier) prend une lambda pour créer la valeur manquante. Ainsi, il n’est plus possible de faire des NPE.

opt.map().orElse("Valeur par défaut")

On peut aussi récupérer la valeur par get() mais une erreur du type NoSuchElementException peut se produire si la valeur n’est pas présente.

 Méthodes utilisables sur les optionals

Méthode Description
orElse Fourni une valeur par défaut
orElseGet Supplier appelé pour générer une valeur
si besoin
ifPresent(Consumer) Déclenche la consommation de l’élément
si présent avec le lambda.

Ainsi on se rend compte que les optionals permettent d’améliorer la lecture du code JAVA. Néanmoins un reproche qui peut lui être fait est que les optionals sont assez verbeux à utiliser. Personnellement même si ils répondent au besoin, j’aurai préférer l’utilisation d’un opérateur type ? qui aurait été plus facile à utiliser.

Pour en savoir plus sur JAVA 8 et bénéficier d’une formation.

L'équipe AXOPEN

Voir aussi les articles suivants

Si vous connaissez la clause try-with-resources introduite par Java 7, vous avez certainement été convaincu par les facilités qu’elle offre quant à la gestion de la fermeture des flux (ainsi que par la diminution de la verbosité de votre code). Un petit rappel toutefois pour ceux qui ne connaîtraient pas… Try-with-resources Le principe est le suivant : pour les flux implémentant l’interface java.lang.AutoCloseable, ce qui inclut tous les flux implémentant l’interface java.
Lire l'article

Nous allons dans cet article découvrir une nouveauté de JAVA 8 bien pratique pour l’interface Map : la méthode computeIfAbsent. Utilisation des maps Un exemple courant d’utilisation des maps est la création de caches applicatifs: on utilise généralement une HashMap dans laquelle on enregistre les éléments que l’on utilise souvent. Chaque élément est indexé par une clé qui permet de retrouver l’élément désiré. La majorité du temps, le fonctionnement d’un tel cas est le suivant : on cherche si l’objet est présent dans le cache, si oui, on le récupère, sinon on le construit et on le stocke dans la HashMap.
Lire l'article

L’utilisation des streams en mode parallèle est très simple d’utilisation. En revanche, il n’est pas forcément évident de savoir si un traitement particulier va bénéficier, ou non, d’une amélioration de performance lors du passage en parallèle. Pour savoir ce qui peut avoir un impact sur les performances, il est nécessaire de comprendre ce qui se passe lorsqu’on lance un traitement en parallèle avec les streams. C’est l’objet de cet article.
Lire l'article