Java 14 : pattern matching avec l’instruction instanceof

Ce cinquième et dernier article de la série détaille l’utilisation possible du pattern matching avec l’instruction instanceof proposée en mode preview en Java 14.

Cet article fait partie d’une série détaillant les principales fonctionnalités proposées dans Java 14 :

 

L’opérateur instanceof permet de vérifier le type d’une variable avant de pouvoir l’utiliser. Cependant, si l’opérateur renvoie true alors il est nécessaire de faire un cast vers une autre variable du type testé

  if (obj instanceof Groupe) {
    Groupe groupe  = (Groupe) obj;
    var    membres = groupe.membres();
  }

Le concept de pattern matching existe déjà dans de nombreux langages. Le but de la JEP 305 est d’introduire dans le langage Java le pattern matching pour l’opérateur instanceof.

Cette fonctionnalité est proposée en mode preview.

 

La mise en oeuvre

Syntaxiquement, il faut faire suivre le type après l’opérateur instanceof par le nom d’une variable.

    if (obj instanceof Groupe groupe) {
       var membres = groupe.membres();
     }

Cela évite d’avoir à préciser plusieurs fois le type pour la déclaration de la variable et pour le cast explicite.

La variable est valorisée avec celle testée si le test est vérifié, sans avoir recours à un cast explicite.

 

La portée de la variable

La portée de la variable extraite est définie en fonction de l’expression qui satisfait la condition.

Par exemple, si la condition est évaluée à true, alors la variable est utilisable dans le bloc de l’instruction if mais pas dans le bloc de l’instruction else.

    if (obj instanceof Groupe groupe) {
      var membres = groupe.membres();
    } else {
      // groupe n’est pas accessible
    }

Attention : il peut aussi y avoir une confusion si le code englobant définit déjà une variable du même nom que celle avec l’instruction instanceof

    if ( !(obj instanceof Groupe groupe)) {
      // groupe n’est pas accessible 
      // sauf si un membre de la classe se nomme groupe
    } else {
      var membres = groupe.membres();
    }

La portée s’applique également dans la déclaration conditionnelle en utilisant l’opérateur &&.

    if (obj instanceof Groupe groupe && !groupe.membres().isEmpty()) {
      System.out.println(groupe.membres());
    }

Evidemment, cela ne fonctionne pas avec l’opérateur ||.

 

La variable extraite est final

La variable utilisée avec le parttern matching est final : il n’est pas possible de lui assigner une autre valeur.

    if (obj instanceof Groupe groupe) {
      var membres = groupe.membres();
      groupe = null;     // erreur à la compilation
    }

 

Le warning émis par le compilateur

L’utilisation de fonctionnalités en mode preview émet un warning de la part du compilateur. Il est possible d’utiliser la valeur «preview» avec l’annotation @SuppressWarnings pour demander au compilateur d’ignorer ce warning.

  @SuppressWarnings("preview")
  public void afficher(Object obj)
    if (obj instanceof Groupe groupe) {
      var membres= groupe.membres();
      // …
    } 
    // …
  }

 

Conclusion

En tant que développeurs, nous utilisons souvent l’opérateur instanceof dans notre code. L’utilisation du pattern matching avec l’instruction instanceof rend le code plus simple et concis ce qui en facilite l’écriture et la lecture.

Une seconde preview défnie dans la JEP 375 est intégrée dans Java 15. Cette seconde preview ne propose aucune évolution mais doit permettre d’allonger la période de feedback.

Le pattern matching va être proposé dans d’autres contextes du langage dans les prochaines versions de Java notamment dans l’instruction switch.