Le cycle de sortie de Java a changé de façon assez profonde récemment, ce qui signifie que nous obtenons de nouvelles fonctionnalités à un rythme plus rapide qu'auparavant. Aujourd'hui nous parlerons de deux fonctionnalités intéressantes du langage.Améliorations au niveau du switch
Selon certains professionnels, l'instruction switch classique en Java n'est pas géniale. Contrairement à de nombreuses autres parties de Java, elle n'a pas été correctement repensée lors du retrait des fonctionnalités de C il y a toutes ces années. Le défaut clé est la "chute par défaut". Cela signifie que si vous oubliez de mettre une clause break dans chaque cas, le traitement se poursuivra jusqu'à la clause case suivante.
Un autre défaut est que les variables sont étendues à l'intégralité du switch, vous ne pouvez donc pas réutiliser un nom de variable dans deux clauses case différentes. De plus, une clause par défaut n'est pas requise, ce qui laisse les lecteurs du code dans l'incertitude quant à savoir si une clause a été ou non oubliée.
Et bien sûr, il y a aussi la principale limitation - le type à activer ne peut être qu'un entier, une énumération ou une chaîne.
| Code Java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 | String instruction; switch (trafficLight) { case RED: instruction = "Stop"; case YELLOW: instruction = "Prepare"; break; case GREEN: instruction = "Go"; break; } System.out.println(instruction); |
Dans le cadre du Project Amber, switch a bénéficié de quelques changements ! Ils ont été lancés en préversion dans JDK 12 et à nouveau dans 13 et sont au moment de la rédaction destinés à être publiés dans JDK 14. Les développeurs vont disposer d'une nouvelle fonctionnalité lorsque switch sera utilisé comme instruction. En outre, il pourra également être utilisé comme une expression à l'avenir.
Bienvenue case X ->
Dans la syntaxe de switch, il est désormais possible de se servir de case X -> en plus du traditionnel case X:. Dans ces cas d'utilisations, seule l'expression ou l'instruction sur le côté droit de la flèche sera exécutée. Cela signifie que vous n'aurez plus besoin de vous rappeler d'utiliser break pour sortir du switch dès lors qu'une languette va correspondre.
| Code Java : | Sélectionner tout |
1 2 3 4 5 6 | String quantityString; switch (n) { case 1 -> quantityString = "one"; case 2 -> quantityString = "two"; default -> quantityString = "many"; } |
switch peut désormais être utilisé comme expressions, c'est-à-dire qu'il peut retourner une valeur. Cela signifie que nous n'aurons pas à déclarer d'abord une variable, puis à affecter une valeur dans chaque branche. Combiné avec des étiquettes de flèche, il nous permet d'exprimer notre intention en beaucoup moins de lignes de code:
| Code Java : | Sélectionner tout |
1 2 3 4 5 | String quantityString = switch (k) { case 1 -> "one"; case 2 -> "two"; default -> "many"; }; |
| Code Java : | Sélectionner tout |
1 2 3 4 5 6 7 8 | DayType type = switch (day) { case 1, 2, 3, 4, 5 -> WEEKDAY; case 6, 7 -> WEEKEND; default -> { logger.warn(day + " is not a valid day. Legal values are [1..7]"); yield UNKNOWN; } }; |
Vous pouvez également transformer les switch d'instruction en expression à l'aide des anciennes étiquettes de style en vous servant de yield.
| Code Java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | Type type = switch (day) { case 1, 2, 3, 4, 5: yield WEEKDAY; case 6, 7: yield WEEKEND; default: logger.warn(day + " is not a valid day."); yield UNKNOWN; }; |
Qu'en pensent les professionnels ?
Le développeur Stephen Colebourne s'est laissé aller à un billet où il soulève quelques questions importantes concernant l'UX de ces fonctionnalités.
« Je ne suis pas convaincu des mérites du nouveau design. Pour être clair, il y a de bons aspects, mais dans l'ensemble, je pense que la solution est trop complexe et avec des choix de syntaxe désagréables.
« L'objectif principal est d'ajouter un formulaire d'expression, où vous pouvez affecter le résultat du switch à une variable. C'est un peu comme l'opérateur ternaire (par exemple. x != Null ? x : ""
« Le plan actuel consiste à ajouter non pas une, mais trois nouvelles formes de commutation. Oui, trois.
- Type 1: déclaration avec syntaxe classique. Comme aujourd'hui. Avec fall-through-by-default. Pas exhaustive.
- Déclaration
- Fall-through-by-default
- retour autorisé, également continue / break une boucle
- Portée unique pour les variables
- La logique pour chaque cas est une séquence d'instructions pouvant se terminer par yield
- Non exhaustif - une clause par défaut n'est pas requise
- yieldle rendement n'est pas autorisé
- Type 2: Expression avec une syntaxe classique. NOUVEAU! Avec fall-through-by-default. Doit être exhaustive.
- Expression
- Fall-through-by-default
- retour non autorisé, impossible de continue / break une boucle
- Portée unique pour les variables
- La logique pour chaque cas peut être une expression de rendement ou une séquence d'instructions se terminant potentiellement par yield
- Exhaustive - une clause par défaut est requise
- Doit utiliser yield pour renvoyer des valeurs
- Type 3: instruction avec nouvelle syntaxe. NOUVEAU! Pas de fall-through. Pas exhaustive.
- Déclaration
- L'interruption n'est pas autorisée
- retour autorisé, ainsi que continue / break sur une boucle
- aucun problème de portée variable, la logique pour chaque cas doit être une instruction ou un bloc
- Non exhaustif - une clause par défaut n'est pas requise
- yield n'est pas autorisé
- Type 4: Expression avec une nouvelle syntaxe. NOUVEAU! Pas de fall-through. Doit être exhaustive.
- Expression
- L'interruption n'est pas autorisée
- retour non autorisé, impossible de continue / break une boucle
- Aucun problème de portée variable, la logique pour chaque cas doit être une expression ou un bloc se terminant par yield
- Exhaustive - une clause par défaut est requise
- Doit utiliser yield pour renvoyer des valeurs, mais uniquement à partir de blocs (c'est implicite quand ce n'est pas un bloc)
Voici un exemple de type 4
| Code Java : | Sélectionner tout |
1 2 3 4 5 6 7 | // type 4 var instruction = switch (trafficLight) { case RED -> "Stop"; case YELLOW -> "Prepare"; case GREEN -> "Go"; }; System.out.println(instruction); |
« Le diable est bien sûr dans le détail.
« Premièrement, un point clairement positif. Au lieu de passer à travers en listant plusieurs étiquettes, elles peuvent être séparées par des virgules :
| Code Java : | Sélectionner tout |
1 2 3 4 5 6 | // type 4 var instruction = switch (trafficLight) { case RED, YELLOW -> "Stop"; case GREEN -> "Go"; }; System.out.println(instruction); |
Ce qu'il dit de tout cela ?
« Les expressions switchde commutateur de type 4 sont correctes (bien que j'ai de réels problèmes avec l'extension de la syntaxe des flèches à partir de lambdas). Mon problème est avec les types 2 et 3. En réalité, ces deux types de switch seront très rares, et donc la plupart des développeurs ne les verront jamais. Compte tenu de cela, je pense qu'il serait préférable de ne pas les inclure du tout. Une fois que cela est accepté, il ne sert à rien de traiter les formes d'expressions comme un switch, car il n'aura en réalité pas beaucoup de connexions avec l'ancienne forme de déclaration. Je laisserais tomber les types 2 et 3 et autoriserais les expressions switch de type 4 à devenir ce qu'on appelle des expressions de déclaration.
| Code Java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 | // Stephen's expression switch var instruction = match (trafficLight) { case RED: "Stop"; case YELLOW: "Prepare"; case GO: "Go"; } // Stephen's expression switch used as a statement (technically a statement expression) match (instruction) { case "Stop": doStop(); case "Go": doGo(); default:[nbsp][/nbsp]; } |
Correspondance de modèle pour instanceof
En tant que développeur Java, vous avez probablement été dans une situation où vous devez vérifier si un objet est d'un certain type, et si c'est le cas - le caster dans ce type. Ce modèle est largement utilisé par exemple dans les implémentations equals.
Introduit en tant que fonctionnalité en préversion dans JDK 14, instanceof est étendu pour prendre ce qu'on appelle un modèle de test de type au lieu d'un simple type. Un modèle de test de type se compose d'un prédicat et d'une variable de liaison.
Prenons cet exemple :
| Code Java : | Sélectionner tout |
1 2 3 4 5 6 7 8 | @Override public boolean equals(Object obj) { if (obj instanceof Person) { Person other = (Person) obj; return this.name == other.name; } return false; } |
| Code Java : | Sélectionner tout |
1 2 3 4 5 6 7 | @Override public boolean equals(Object obj) { if (obj instanceof Person other) { return this.name == other.name; } return false; } |
Dans le bloc if, vous pouvez utiliser other et il est garanti qu'il s'agit d'une Person. En revanche, other n'est pas accessible en dehors du bloc if.
| Code Java : | Sélectionner tout |
1 2 3 4 5 | if (!(obj instanceof String s)) { System.out.println(s); // 1 } else { System.out.println(s); // 2 } |
Les nouveaux changements switch ont actuellement le drapeau préversion dans la version JDK la plus récente (13). Cela signifie que vous ne devez probablement pas les utiliser dans une large mesure dans la base de code qui constitue votre gagne-pain. Les API peuvent changer et il y a toujours une chance que la fonctionnalité ne soit pas promue en fonction stable dans sa forme actuelle.
Il est cependant utile de les expérimenter. Essayer de nouvelles fonctionnalités est un bon moyen d'élargir votre ensemble de compétences, et s'il y a quelque chose que vous n'aimez pas du tout quant à la convivialité d'une fonctionnalité, vous pouvez même fournir des commentaires aux développeurs JDK.
Pour commencer à expérimenter les préversions de ces fonctionnalités sur l'outil dont vous vous servez, il vous suffit de suivre les instructions ci-dessous:
Maven
Pour activer pendant la compilation, ajoutez la configuration suivante à maven-compiler-plugin:
| Code Java : | Sélectionner tout |
1 2 3 4 5 6 | <configuration>
<release>13</release>
<compilerArgs>
--enable-preview
</compilerArgs>
</configuration> |
| Code Java : | Sélectionner tout |
1 2 3 | <configuration>
<argLine>--enable-preview</argLine>
</configuration> |
Activez l'indicateur du compilateur pour la compilation et l'exécution des tests comme suit:
| Code Java : | Sélectionner tout |
1 2 3 4 5 6 | compileJava { options.compilerArgs += ["--enable-preview"] } test { jvmArgs '--enable-preview' } |
Accédez à Paramètres du projet> Projet et recherchez la liste déroulante Niveau de langage du projet. Si vous avez précédemment ciblé la version 13 et que vous souhaitez activer les fonctionnalités en préversion, choisissez 13 (Preview).
Sources : billet Stephen Colebourne, OpenJDK (switch, instanceOf)
Voir aussi :
Vaudra-t-il encore la peine de consacrer du temps à l'étude du langage Java en 2020 ? Voici 10 raisons de répondre à l'affirmative, selon l'éditeur du blog Javarevisited
L'extrait de code Java le plus copié sur Stack Overflow contient un bogue et son auteur, Andreas Lundblad, développeur Java chez Palantir, propose un correctif
Entre Java et Kotlin, lequel de ces langages est le meilleur pour le développement d'applications Android ?
SQL et Java sont encore les compétences techniques les plus demandées en 2019, selon un rapport d'étude
Vous avez lu gratuitement 2 651 articles depuis plus d'un an.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.

, cela doit être indiqué que l'identifiant ne doit pas être vide, avoir ...