Come un'istruzione if/else, un'istruzione switch ti permette di cambiare il flusso del programma eseguendo del codice in modo condizionale.
La differenza è che un'istruzione switch può confrontare il valore di un'espressione primitiva o di una stringa solo con valori costanti predefiniti.
Alcune parole chiave sono utili quando si usa un'istruzione switch.
switch: questa parola chiave ti permette di dichiarare la struttura dello switch.
È seguita dall'espressione o dalla variabile che farà cambiare il risultato.case: userai questa per dichiarare le diverse possibilità per il risultato.break: la parola chiave break è molto utile per fermare l'esecuzione dello switch alla fine del flusso desiderato.
Se la dimentichi, il programma continuerà e potrebbe portare a risultati inattesi.default: come dice il nome, usala come risultato predefinito quando nessun altro caso corrisponde al risultato della tua espressione.Nella loro forma più semplice, verificano un'espressione primitiva o una stringa e prendono una decisione in base al suo valore. Per esempio:
String direction = getDirection();
switch (direction) {
case "left":
goLeft();
break;
case "right":
goRight();
break;
default:
// otherwise
markTime();
break;
}
A partire da Java 14 (disponibile come anteprima nelle versioni precedenti, Java 12 e 13) è possibile usare l'implementazione «enhanced» dello switch.
Hai la possibilità di assegnare più valori a un singolo caso.
Nell'istruzione switch tradizionale puoi usare il fall-through. Nell'esempio seguente, case 1 e case 3 eseguiranno la stessa cosa.
Questo accade perché case 1 non usa la parola chiave break.
switch (number) {
case 1:
case 3:
// do same stuff
break;
case 2:
// do different stuff
break;
// (...)
}
Nello switch expression enhanced puoi assegnare direttamente più valori a un case.
Guarda l'esempio seguente:
switch (number) {
case 1, 3:
// do stuff
break;
case 2:
// do other stuff
break;
// (...)
}
Ora puoi scrivere uno switch-statement oppure uno switch expression.
Qual è la differenza?
In pratica, un'istruzione si aspetta una logica rigida, mentre un'espressione può restituire un valore.
Invece di:
String result = "";
switch (expression) {
case "bob":
result = "bob";
break;
// (...)
}
Puoi fare:
String result = switch (expression) {
case "bob":
yield "bob";
// (...)
}
Lo yield funziona come un return, con la differenza che è pensato per le switch expression.
Dato che yield termina l'espressione, qui break non serve.
Un'altra differenza tra switch statements e switch expressions: nelle switch expressions devi coprire tutti i casi.
O avendo un case per ogni valore possibile, oppure usando un caso default.
Puoi usare -> al posto di :.
Il -> ti permette di non includere la parola chiave break.
Entrambe le notazioni si possono usare, ma in uno switch devi attenerti a una sola.
switch(expression) {
case 1 -> yield "one"
case 2 -> yield "two"
default: yield "other number" // Removing this will result in a compile error
}
Lo scope.
Lo switch tradizionale può portare a comportamenti inattesi a causa del suo scope, perché c'è un solo scope per l'intero switch.
switch(expression) {
case 1:
String message = "something";
break;
case 2:
String message = "anything";
break;
// (...)
}
Questo esempio non funziona perché message viene dichiarato due volte nello switch.
Si potrebbe risolvere così:
switch (expression) {
case 1: {
String message = "something";
break;
}
case 2: {
String message = "anything";
break;
}
// (...)
}
Dato che le {} delimitano lo scope del case.
Però non è intuitivo, perché le {} non sono obbligatorie.
Tuttavia, se usi la nuova notazione ->, questa deve essere seguita da: una singola istruzione/espressione, un'istruzione throw o un blocco {}.
Niente più confusione!
Puoi trovare maggiori informazioni sullo switch enhanced in questo articolo e questo altro, insieme alla documentazione ufficiale Oracle.
Inoltre, in Java 21 è stata aggiunta una funzionalità chiamata Guarded Patterns, che ti permette di eseguire dei controlli direttamente nell'etichetta del 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";
};
Puoi trovare maggiori informazioni sullo switch expression in Java 21 in questo blog