Comme une instruction if/else, une instruction switch permet de modifier le déroulement du programme en exécutant du code de manière conditionnelle.
La différence, c'est qu'une instruction switch ne peut comparer la valeur d'une expression primitive ou string qu'à des valeurs constantes prédéfinies.
Certains mots-clés sont utiles lorsqu'on utilise une instruction switch.
switch : ce mot-clé permet de déclarer la structure du switch.
Il est suivi de l'expression ou de la variable qui fera changer le résultat.case : tu utiliseras celui-ci pour déclarer les différentes possibilités de résultat.break : le mot-clé break est très utile pour arrêter l'exécution du switch à la fin du flux souhaité.
Si tu l'oublies, le programme continuera et pourra produire des résultats inattendus.default : comme son nom l'indique, utilise-le comme résultat par défaut lorsqu'aucun autre case ne correspond au résultat de ton expression.Dans leur forme la plus simple, ils testent une expression primitive ou string et prennent une décision en fonction de sa valeur. Par exemple :
String direction = getDirection();
switch (direction) {
case "left":
goLeft();
break;
case "right":
goRight();
break;
default:
// otherwise
markTime();
break;
}
À partir de Java 14 (disponible en aperçu dans Java 12 et 13), il est possible d'utiliser l'implémentation « améliorée » du switch.
Tu as la possibilité d'affecter plusieurs valeurs à un seul case.
Dans l'instruction switch traditionnelle, tu peux utiliser le fall-through.
Dans l'exemple suivant, case 1 et case 3 exécuteront le même code.
C'est possible parce que case 1 n'utilise pas le mot-clé break.
switch (number) {
case 1:
case 3:
// do same stuff
break;
case 2:
// do different stuff
break;
// (...)
}
Dans une switch expression améliorée, tu peux affecter directement plusieurs valeurs à un case.
Regarde l'exemple suivant :
switch (number) {
case 1, 3:
// do stuff
break;
case 2:
// do other stuff
break;
// (...)
}
Tu peux maintenant écrire un switch-statement ou une switch expression.
Quelle est la différence ?
En gros, une instruction attend une logique stricte, alors qu'une expression peut renvoyer une valeur.
Au lieu de :
String result = "";
switch (expression) {
case "bob":
result = "bob";
break;
// (...)
}
Tu peux faire :
String result = switch (expression) {
case "bob":
yield "bob";
// (...)
}
Le yield fonctionne comme un return, sauf qu'il est destiné aux expressions switch.
Comme yield termine l'expression, break n'est pas nécessaire ici.
Une autre différence entre les instructions switch et les expressions switch : dans les expressions switch, tu DOIS couvrir tous les cas.
Soit en prévoyant un case pour toutes les valeurs possibles, soit en utilisant un default.
Tu peux utiliser -> à la place de :.
Le -> te permet de ne pas inclure le mot-clé break.
Les deux notations peuvent être utilisées, mais au sein d'un même switch, tu dois t'en tenir à une seule.
switch(expression) {
case 1 -> yield "one"
case 2 -> yield "two"
default: yield "other number" // Removing this will result in a compile error
}
La portée.
Un switch traditionnel peut avoir un comportement inattendu à cause de sa portée, puisqu'il n'existe qu'une seule portée pour tout le switch.
switch(expression) {
case 1:
String message = "something";
break;
case 2:
String message = "anything";
break;
// (...)
}
Cet exemple ne fonctionne pas, car la variable message est déclarée deux fois dans le switch.
On peut le résoudre ainsi :
switch (expression) {
case 1: {
String message = "something";
break;
}
case 2: {
String message = "anything";
break;
}
// (...)
}
car les {} délimitent la portée du case.
Cependant, ce n'est pas intuitif, car les {} ne sont pas obligatoires.
En revanche, si tu utilises la nouvelle notation ->, elle doit être suivie soit d'une instruction ou d'une expression unique, soit d'une instruction throw, soit d'un bloc {}.
Fini la confusion !
Tu trouveras plus d'informations sur le switch amélioré dans cet article et celui-ci, ainsi que dans la documentation officielle Oracle.
De plus, une fonctionnalité appelée Guarded Patterns a été ajoutée dans Java 21 ; elle te permet d'effectuer des vérifications directement dans l'étiquette du case.
String dayOfMonth = getDayOfMonth();
String day = "";
return switch (day) {
case "Tuesday" when dayOfMonth == 13 -> "Forbidden day!!";
case "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" -> "Week day";
case "Saturday", "Sunday" -> "Weekend";
default -> "Unknown";
};
Tu trouveras plus d'informations sur l'expression switch de Java 21 dans ce blog