A cosa serve switch
Uno switch confronta un valore con un elenco di opzioni fisse ed esegue il ramo che corrisponde. Quando ti ritrovi a scrivere una lunga catena if/else if che continua a confrontare la stessa variabile con costanti diverse, uno switch dice la stessa cosa in modo più chiaro.
Fa solo controlli di uguaglianza con costanti note in fase di compilazione: non può verificare intervalli né combinare condizioni. Per quello, resta su if/else.
Lo switch classico
La forma tradizionale usa etichette case con i due punti e un break dopo ogni ramo:
Java valuta day, salta al case corrispondente, esegue le sue istruzioni e il break esce dallo switch. Il ramo default viene eseguito quando nessun altro corrisponde: consideralo l'else. È facoltativo, ma è buona pratica includerlo così i valori inattesi non passano in silenzio.
La trappola del break: il fall-through
È il bug più comune in assoluto con switch. Se ometti un break, l'esecuzione non si ferma alla fine del case corrispondente: prosegue nel case successivo e continua finché non incontra un break o la graffa di chiusura:
Potresti aspettarti solo Level 1, ma vengono stampate tutte e tre le righe. Poiché case 1 non ha un break, il controllo scivola dritto in case 2 e case 3. Aggiungi sempre break, a meno che tu non voglia davvero il fall-through; e quando ci fai affidamento, lascia un commento così chi legge sa che è voluto.
Raggruppare i case
Il fall-through ha un uso legittimo e ordinato: impilare le etichette case così più valori condividono lo stesso blocco. Metti le etichette una dopo l'altra senza codice in mezzo:
Qui 'A', 'B' e 'C' eseguono tutti la stessa riga "Pass". È il modo previsto per dire "uno qualsiasi di questi valori fa la stessa cosa".
switch sulle stringhe
Non sei limitato ai numeri. Da Java 7 puoi fare switch su una String, perfetto per scelte di menu o nomi di comandi:
Il confronto distingue maiuscole e minuscole: "Stop" non corrisponderebbe a "stop", quindi normalizza prima l'input (per esempio con command.toLowerCase()) se le maiuscole possono variare. Un'altra trappola: se command è null, lo switch lancia una NullPointerException, quindi proteggiti dal null prima di arrivarci.
La sintassi moderna con la freccia
Il Java più recente (14+) aggiunge una forma con la freccia, case label -> ..., che elimina per costruzione la trappola del fall-through. Ogni case con la freccia esegue esattamente un ramo e non prosegue mai nel successivo, quindi non c'è nessun break da dimenticare:
Nota che raggruppi i valori con una virgola (case 6, 7) invece di impilare le etichette, e che non c'è nemmeno un break. Per più istruzioni usa un blocco: case 1 -> { ...; ... }. Preferisci questa forma nel codice nuovo: è più corta ed elimina un'intera categoria di bug.
switch come espressione
La forma con la freccia può anche produrre un valore. Una switch expression restituisce un risultato che puoi assegnare direttamente a una variabile, senza variabili temporanee e senza ripetere l'assegnazione in ogni ramo:
L'intero switch (...) { ... } produce un numero che viene salvato in days. Nota il punto e virgola dopo la graffa di chiusura: fa parte dell'istruzione di assegnazione. Una switch expression deve essere esaustiva (coprire ogni valore possibile), ed è per questo che qui c'è default; nota anche che un ramo senza corrispondenza può lanciare un'eccezione invece di restituire un valore. Se un ramo ha bisogno di più istruzioni prima di restituire un valore, usa un blocco con yield:
case 2 -> {
boolean leap = (year % 4 == 0);
yield leap ? 29 : 28;
}
yield è il modo in cui un blocco con la freccia restituisce il suo valore: l'equivalente, nel mondo delle espressioni, di un break che porta con sé un risultato.
Prossima pagina: cicli for
switch sceglie un ramo tra tanti; a volte invece devi ripetere un blocco molte volte. Il ciclo for esegue il codice un numero controllato di volte, contando in un intervallo o passando su ogni elemento, ed è l'argomento della prossima pagina.
Domande frequenti
Quando usare switch invece di if-else in Java?
Usa switch quando confronti un solo valore con tante opzioni costanti e fisse, come il numero di un giorno, una scelta di menu o un enum. Si legge meglio di una lunga catena if/else if e comunica "scegli un ramo tra questi valori noti". Resta su if/else quando le condizioni riguardano intervalli (x > 10), più variabili o qualsiasi cosa che non sia un semplice controllo di uguaglianza con una costante.
Perché serve break in uno switch in Java?
Con la sintassi classica a due punti, quando un case corrisponde, l'esecuzione prosegue nei case successivi finché non incontra un break o la fine dello switch. break la ferma. Dimenticarlo è un bug classico: corrisponde case 1: e per sbaglio esegui anche il codice di case 2:, case 3: e così via. La sintassi più recente con la freccia (case 1 -> ...) non prosegue mai nei case successivi, quindi break non si scrive affatto.
Uno switch in Java funziona con le stringhe?
Sì. Da Java 7 puoi fare switch su una String, e puoi farlo anche su int, char, byte, short, sui loro tipi wrapper e sui valori di un enum. Non puoi fare switch su long, double, float o boolean. Il confronto tra stringhe distingue maiuscole e minuscole, quindi "Yes" e "yes" sono case diversi.