Nouveautés Java SE : une petite étude de cas
Switch, case, default et break – notre expert en Java, Dominic A. Merz, nous explique quelles possibilités offrent les nouveautés pour la programmation Java.
Qu’est-ce qu’on peut se casser la tête, tant dans la pratique que lors d’examens, avec la bonne utilisation des mots clés switch, case, default et break dans un branchement conditionnel !
En particulier les possibles types de données des variables utilisables dans un bloc switch(), la nature des constantes dans les instructions case, l’emplacement de l’instruction par défaut (default) et l’abandon de l’instruction break, de manière délibérée (dans le cas d’un fall through) ou involontaire (dans le cas d’une erreur), peuvent souvent nous désorienter dans le cadre de la structure de contrôle switch.
Dans tous les cas, deux choses sont certaines :
- De manière générale, un branchement conditionnel avec switch()/case/default est plus performant qu’une sélection de cas identique avec les instructions if()/else if()/else.
- Cette structure inspire sans cesse des questions formidables pour l’examen de certification.
Observons tout d’abord l’utilisation traditionnelle à l’aide d’un exemple (voir Listing 001 et Console 001). Dans cet exemple, le nombre de jours d’un mois (entré en anglais) d’une année ordinaire est retourné et exprimé par une standard output. (Oui, ça ne marche pas pour l’année 2020. Et oui, ça serait bien plus facile d’utiliser l’API Date/Time de Java SE 8 pour ça).
Listing 001
001 package example;
002
003 public class Application {
004
005 public static void main(String args) {
006 String nameOfMonth = args0;
007 int numberOfDays;
008 switch (nameOfMonth) {
009 default:
010 numberOfDays = 0;
011 break;
012 case "February":
013 numberOfDays = 28;
014 break;
015 case "April":
016 case "June":
017 case "September":
018 case "November":
019 numberOfDays = 30;
020 break;
021 case "January":
022 case "March":
023 case "Mai":
024 case "July":
025 case "August":
026 case "October":
027 case "December":
028 numberOfDays = 31;
029 break;
030 }
031 System.out.printf("%d days.%n", numberOfDays);
032 }
033 }
Console 001
>javac example\Application.java
>java example.Application January
31 days.
>
La JEP 325 du JDK 12 et la JEP 354 du JDK 13 nous propose une preview d’une série d’ajustements et d’améliorations qui devraient permettre de simplifier l’utilisation des branchements conditionnels. (La version finale arrivera sans doute avec la JEP 361 du JDK 14).
Ainsi, nous pouvons par exemple, résumer plusieurs instructions case en énumérant les valeurs correspondantes sous la forme d’une liste dont les valeurs sont séparées par une virgule (voir Listing 002 et Console 002).
Listing 002
001 package example;
002
003 public class Application {
004
005 public static void main(String args) {
006 String nameOfMonth = args0;
007 int numberOfDays;
008 switch (nameOfMonth) {
009 default:
010 numberOfDays = 0;
011 break;
012 case "February":
013 numberOfDays = 28;
014 break;
015 case "April", "June", "September", "November":
016 numberOfDays = 30;
017 break;
018 case "January", "March", "Mai", "July", "August", "October",
019 "December":
020 numberOfDays = 31;
021 break;
022 }
023 System.out.printf("%d days.%n", numberOfDays);
024 }
025 }
Console 002
>javac --enable-preview --source 13 example\Application.java
>java –enable-preview example.Application January
31 days.
>
De plus, il est maintenant possible d’utiliser un branchement conditionnel non seulement en tant qu’instruction, mais aussi comme expression – voir Listing 003 et Console 003 pour un exemple d’une affectation compacte. (À qui cela ne rappelle-t-il pas la structure alternative compacte et son expression conditionnelle ternaire ?: ?)
Dans ce cas, nous entrons simplement et rapidement, après le nouveau mot-clé yield, la valeur retournée choisie et refermons bien entendu l’affectation après le bloc avec un point-virgule. (voir Listing 003, Ligne 017)
Listing 003
001 package example;
002
003 public class Application {
004
005 public static void main(String args) {
006 String nameOfMonth = args0;
007 int numberOfDays = switch (nameOfMonth) {
008 default:
009 yield 0;
010 case "February":
011 yield 28;
012 case "April", "June", "September", "November":
013 yield 30;
014 case "January", "March", "Mai", "July", "August", "October",
015 "December":
016 yield 31;
017 };
018 System.out.printf("%d days.%n", numberOfDays);
019 }
020 }
Console 003
>javac --enable-preview --source 13 example\Application.java
>java –enable-preview example.Application January
31 days.
>
Ces nouveautés nous simplifient l’utilisation des branchements conditionnels et raccourcissent le code nécessaire. De plus, nous avons maintenant droit à un flux de contrôle plus clair qui ne laisse plus passer un fall through ou un break oublié.
Et il y a deux choses qui sont encore toujours certaines :
- Comme le diraient nos collègues suisse-allemand «Chamer mache, muemer aber nööd.» (« on peut faire comme ça, mais on n’est pas obligé »).
- Cette nouvelle structure inspire encore plus de questions formidables pour l’examen de certification.