Accueil Nos publications Blog Java 14 : Évolution du switch

Java 14 : Évolution du switch

Java 14 est sorti en mars 2020 en apportant plusieurs nouveautés. L’une d’elles concerne l’utilisation du switch qui a connu de nombreux changements à partir de Java 12.
Cet article présentera en première partie la syntaxe standard du switch dans les versions antérieures à Java 12, tout en évoquant ces principaux inconvénients. Nous verrons ensuite comment l’utilisation du switch a été succesivement améliorée entre les versions 12, 13 puis 14.

Partie 1 : Switch avant Java 12

Pour bien comprendre pourquoi le switch a dû évoluer, analysons la syntaxe telle qu’elle était proposée avant Java 12 à l’aide d’un exemple simple. Nous créons une enumSaison contenant les 4 saisons (PRINTEMPS, ETE, AUTOMNE et HIVER), puis nous utilisons un switch, qui en fonction de la saison nous renverra la météo correspondante :

Note : le code ci-dessus a été développé avec la JDK-11.0.7

Ce que l’on constate c’est le nombre de lignes qu’il a fallu rédiger, le switch est trop verbeux.

De plus, l’instruction break est répétée dans chaque case (indiquant de sortir du switch une fois le traitement effectué dans la branche dédiée), ce qui alourdit considérablement la syntaxe.

Dans notre exemple, les cases PRINTEMPS et ETE effectuent le même traitement, nous pourrions les regrouper en ne mettant pas d’instruction dans le case PRINTEMPS puis en valorisant notre variable meteo dans le case ETE :

Toutefois là encore le code reste conséquent.

Note : on pourrait simplifier davantage notre exemple en mettant le switch dans une méthode, puis en répétant l’instruction return de la valeur à renvoyer dans chacune des branches. Nous allons toutefois voir qu’à partir de Java 12 nous pourrons faire mieux pour optimiser le code.

Ainsi, bien que le switch ait permis à l’origine de remplacer l’usage des multiples if/else, il possède une syntaxe lourde, peu pratique, qui ne facilite pas la lecture du code.

Heureusement ces lacunes vont être progressivement corrigées dans les versions 12 et 13 de Java. Dans la partie qui suit, nous allons voir comment le switch a été optimisé avec Java 12.

Partie 2 : Evolution du switch en Java 12

2.1] Environnement de tests

La [JEP 325] fait référence aux propositions d’améliorations apportées au switch. Elles ont été livrées sous une forme non finalisée, c’est-à-dire en preview, ce qui signifie qu’elles sont disponibles dans la JDK 12 sous forme d’expérimentation pouvant être amenées à évoluer (voire être supprimées) et à ce titre elles sont donc désactivées par défaut (d’autant qu’à ce stade elles ne sont pas destinées à une utilisation en production).

Avant d’étudier ces améliorations, sachez que tous les exemples de ce cours ont été rédigés avec le [JShell], cela vous permettra de les tester rapidement sans avoir besoin de créer tout un projet :

Note : dans cette partie du cours c’est la JDK-12.0.2 qui est utilisée.

Observez l’option qui suit la commande JShell, –enable-preview.
C’est grâce à elle que nous allons activer les fonctionnalités en cours d’expérimentation, notamment celles concernant le switch.

Maintenant que tout est prêt, créons notre enum dans le JShell ainsi que nos variables saison et meteo :

2.2] Mise en commun des branches communes

En introduction nous avions vu que pour mettre en commun les branches PRINTEMPS et ETE, nous laissions le case PRINTEMPS sans instruction, puis nous valorisions notre variable meteo dans le case ETE. Et bien avec Java 12 nous allons pouvoir faire mieux pour optimiser le code :

Et à l’exécution nous obtenons bien le résultat attendu :

Malheureusement ce n’est pas suffisant, il nous reste encore beaucoup de lignes dont ces instructions break à répétition.
Et bien nous allons maintenant voir ce qui fait la nouveauté majeure de Java 12, l’utilisation des Lambdas.

2.3] Utilisation des lambdas

Grâce aux lambdas introduites en Java 8, nous allons pouvoir considérablement raccourcir notre switch :

Que constate-t-on ?
Les break ont disparu ! En utilisant les lambdas, il n’est désormais plus nécessaire d’y avoir recours.
Si l’on teste notre nouveau switch, notre variable meteo est correctement valorisée :

Note : vous ne pouvez pas mélanger la syntaxe standard du switch ( case [condition]: ) ET les lambdas (case [condition] -> ), vous obtiendriez une erreur.

Sachez que nous pouvons encore améliorer notre code, grâce au changement le plus important qu’apporte Java 12 : il est possible d’utiliser le switch en tant qu’expression à part entière !

2.4] Switch en tant qu’expression

Jusqu’à maintenant, le switch était utilisé en tant que structure de contrôle, afin d’évaluer une expression puis exécuter l’instruction correspondante dans la branche dédiée.
Avec Java 12 nous allons désormais pouvoir l’utiliser en tant qu’expression. À l’aide de l’exemple précédent, voyons ce que cela nous apporte :

Comme nous pouvons le constater, il est à présent possible d’assigner le retour d’un switch à une variable !
Ainsi, il n’est plus nécessaire de valoriser la variable meteo à chacune des branches.
Notez toutefois que vous devriez alors terminer votre switch avec un point-virgule, sous peine d’avoir un message d’erreur.
À l’exécution nous obtenons donc :

Pour finir cette partie, sachez qu’il est également possible d’assigner le résultat du switch à une variable en utilisant sa syntaxe standard :

Vous devrez alors réutiliser les break. En revanche, ils seront directement suivis par la valeur à renvoyer.

Nous venons d’aborder les principales nouveautés qu’apporte Java 12 sur le switch. Voyons maintenant ce qu’apporte la version 13.

Partie 3 : Switch en Java 13

En Java 13 c’est la [JEP 354] qui fait référence aux propositions d’évolutions à apporter au switch.
Dans cette version, les évolutions précédentes ainsi que celle présentée ici restent en preview. Pour pouvoir les utiliser, il va donc falloir les activer :

Note : Au cours de cette partie c’est la JDK-13.0.1 qui est utilisée.

La principale nouveauté qu’apporte Java 13 sur le switch est l’ajout d’un nouveau mot clé : yield !

Avant d’expliquer son utilité, reprenons l’exemple précédent :

Dans cet exemple issu de Java 12, nous utilisions le mot clé break pour sortir du switch, puis nous renvoyions le résultat correspondant à la branche où nous étions.
Cette syntaxe est toutefois déroutante à la lecture quant à la signification d’une "pause [résultat]".
Afin de faciliter la compréhension de l’instruction et de marquer une vraie séparation avec le break des anciennes versions, le mot clé yield a été introduit pour le remplacer :

À l’exécution nous obtenons le même résultat :

Le yield est donc l’équivalent d’une instruction return mais dédié au switch. À son exécution, vous sortirez du switch mais pas de votre méthode.

Note : vous ne pourrez plus utiliser le mot-clé break dans ce cas, vous obtiendriez une erreur.

Reprenons maintenant la syntaxe initiale du switch :

Si nous essayons de remplacer le break par yield, le code ne sera pas valide :

Il faut donc bien noter que :
Le mot clé yield ne s’utilise que lorsque vous vous servez du switch en tant qu’expression.
Si vous l’utilisez en tant que structure de contrôle (et sous cette forme), c’est le mot-clé break qui est à utiliser sous peine d’avoir une erreur.

Voici donc la principale nouveauté qu’apporte Java 13 sur les switch. Voyons maintenant ce qu’apporte Java 14.

Partie 4 : Switch en Java 14

En Java 14 c’est la [JEP 361] qui fait référence au switch.
La nouveauté est majeure : toutes les améliorations apportées au switch deviennent officiellement des standards du langage !
Cela signifie que les propositions de changements ont été validées et peuvent à présent être utilisées sur vos projets.

En installant la dernière version de Java, vous n’aurez donc plus besoin de préciser que vous voulez activer les fonctionnalités en preview :

Récapitulons les évolutions majeures apportées au switch :

  • Sa syntaxe a été largement simplifiée. Elle devient plus concise grâce à l’utilisation des lambdas.
  • Switch est utilisable en tant qu’expression : on peut maintenant affecter le retour d’un switch à une variable.
  • Un nouveau mot clé a fait son apparition, yield, afin de faciliter la lecture du code. Il correspond à l’instruction return, mais dédiée au switch.

Conclusion

L’amélioration du switch a permis de le rendre moins verbeux et plus simple d’utilisation. Grâce à cela, une autre fonctionnalité de Java va pouvoir être optimisée : le pattern matching pour l’opérateur instanceOf. Cette optimisation a d’ailleurs déjà commencé au travers d’une preview en Java 14, c’est la [JEP 305] qui y fait référence.

© SOAT
Toute reproduction interdite sans autorisation de la société SOAT