1. Cosa c’è di nuovo in switch
Se hai scritto in Java prima della versione 14, lo switch appariva più o meno così:
switch (day)
{
case MONDAY:
System.out.println("Inizio della settimana!");
break;
case FRIDAY:
System.out.println("Venerdì, evviva!");
break;
default:
System.out.println("Giornata normale.");
break;
}
Sembra nulla di terribile, però:
- Non bisogna dimenticare il break (altrimenti si «cade» nel case successivo).
- Molto codice ripetitivo.
- Se vuoi restituire un valore, devi dichiarare una variabile in anticipo e assegnarle un valore dentro ogni case.
Java 14+ ha deciso: basta così! È ora di rendere lo switch più comodo e moderno.
Novità principali:
- Switch è diventato un’espressione, non solo un’istruzione — ora può restituire un valore.
- Nuova sintassi con la freccia -> al posto dei due punti e di break.
- Più case separati da virgola — per la stessa logica.
- Il compilatore verifica che tutte le alternative siano gestite (soprattutto con enum).
- Nessun rischio di «fall-through» — ora è possibile solo esplicitamente.
2. Sintassi dell’espressione switch
switch (znachenie)
{
case A, B -> rezultat1;
case C -> {
// diverse azioni
yield rezultat2;
}
default -> rezultatPoUmolchaniyu;
}
-> e
yield
Esempio base
Andiamo subito al sodo. Ecco come ora si può restituire un valore da switch:
DayOfWeek day = DayOfWeek.MONDAY;
String message = switch (day)
{
case MONDAY, FRIDAY, SUNDAY -> "Settimana corta o giorno festivo!";
case TUESDAY -> "Il martedì è una giornata pesante.";
case WEDNESDAY, THURSDAY -> "Metà settimana!";
case SATURDAY -> "Evviva, sabato!";
// Il default è obbligatorio se non tutti i casi sono coperti
default -> "Una giornata un po' strana...";
};
System.out.println(message);
Che cosa succede qui:
- switch (day) è un’espressione che restituisce un valore.
- Dopo la freccia -> si indica il risultato per quel case.
- Più case possono essere uniti con la virgola.
- Non c’è alcun break — Java sa da sola dove termina il ramo.
- Si può assegnare direttamente il risultato alla variabile message.
Esempio con i numeri
int code = 404;
String result = switch (code)
{
case 200 -> "OK";
case 400, 404 -> "Errore del client";
case 500 -> "Errore del server";
default -> "Codice sconosciuto";
};
System.out.println(result);
Esempio con le stringhe
String command = "start";
String status = switch (command)
{
case "start" -> "Avvio!";
case "stop" -> "Arresto!";
case "pause" -> "Pausa...";
default -> "Comando sconosciuto";
};
System.out.println(status);
Uso di un blocco con yield
A volte vuoi eseguire più azioni per un unico case (per esempio, calcolare qualcosa di complesso o fare logging). Per questo puoi usare un blocco { ... } e la parola chiave yield:
int n = 7;
String parity = switch (n % 2)
{
case 0 -> "Pari";
case 1 ->
{
System.out.println("Rilevato numero dispari: " + n);
yield "Dispari";
}
default -> "Qualcosa di strano";
};
System.out.println(parity);
Importante: nel blocco deve esserci yield, che restituisce il valore per quel case.
3. Vantaggi della nuova sintassi
Nessuna necessità di break
Nello switch classico un break dimenticato è fonte di dolore e bug misteriosi. Nella nuova sintassi break non serve affatto: ogni ramo termina automaticamente.
Il compilatore verifica la copertura di tutti i casi
Se usi un enum e non gestisci tutti i valori, il compilatore non lascerà compilare il progetto senza default. Questo rende il codice più affidabile.
Nessun «fall-through»
Nello switch classico, se dimentichi il break, l’esecuzione «cade» nel case successivo. Con la nuova sintassi questo non è possibile (a meno che tu non usi un blocco con istruzioni e scriva esplicitamente break — ma qui non serve).
Codice più compatto e leggibile
Confronta tu stesso:
Prima:
String result;
switch (status) {
case "OK":
result = "Tutto bene";
break;
case "ERROR":
result = "Errore";
break;
default:
result = "Sconosciuto";
break;
}
Dopo:
String result = switch (status) {
case "OK" -> "Tutto bene";
case "ERROR" -> "Errore";
default -> "Sconosciuto";
};
Più case — una sola logica
case MONDAY, FRIDAY, SUNDAY -> "Giorno festivo o giornata corta!";
4. Confronto con lo switch classico
| Caratteristica | Switch classico | Nuovo switch |
|---|---|---|
| break obbligatorio | Sì | No |
| Fall-through | Sì | No |
| Può restituire un valore | No (solo tramite variabile) | Sì (espressione) |
| Più case separati da virgola | No | Sì |
| Verifica di tutti i casi | No | Sì (soprattutto con enum) |
| Compattezza | Molto codice | Breve e chiaro |
| Uso con enum e stringhe | Sì | Sì |
5. Compatibilità con enum e stringhe
Esempio con enum
Supponiamo di avere un’enumerazione:
enum DayOfWeek
{
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
Usiamola nel nuovo switch:
DayOfWeek today = DayOfWeek.WEDNESDAY;
String mood = switch (today)
{
case MONDAY -> "È dura alzarsi...";
case FRIDAY -> "Il weekend è vicino!";
case SATURDAY, SUNDAY -> "Evviva, riposo!";
default -> "Giornata lavorativa.";
};
System.out.println(mood);
Esempio con String
String season = "summer";
String activity = switch (season)
{
case "winter" -> "Pattinare sul ghiaccio";
case "summer" -> "Nuotare nel lago";
case "autumn" -> "Raccogliere funghi";
case "spring" -> "Ascoltare il canto degli uccelli";
default -> "Stagione sconosciuta";
};
System.out.println(activity);
6. Riscriviamo il vecchio switch nel nuovo stile
Prima:
int day = 3;
String dayName;
switch (day)
{
case 1:
dayName = "Lunedì";
break;
case 2:
dayName = "Martedì";
break;
case 3:
dayName = "Mercoledì";
break;
default:
dayName = "Giorno sconosciuto";
break;
}
System.out.println(dayName);
Dopo:
int day = 3;
String dayName = switch (day)
{
case 1 -> "Lunedì";
case 2 -> "Martedì";
case 3 -> "Mercoledì";
default -> "Giorno sconosciuto";
};
System.out.println(dayName);
Altro esempio: più case — una sola logica
int score = 5;
String grade = switch (score)
{
case 5, 6, 7 -> "Buono";
case 8, 9, 10 -> "Eccellente";
default -> "Bisogna impegnarsi";
};
System.out.println(grade);
7. Errori tipici e particolarità
Errore n. 1: assenza di default se non tutti i casi sono gestiti. Se utilizzi un’espressione switch con un tipo che può avere valori al di fuori dei case elencati (ad esempio con int o String), il compilatore richiederà il default. Per gli enum, se non gestisci tutti i valori, default è comunque obbligatorio.
Errore n. 2: dimenticare yield nel blocco. Se usi le parentesi graffe per un case (bisogna eseguire più azioni), non dimenticare yield — senza di esso il compilatore darà l’errore: "Missing yield statement".
Errore n. 3: tipi non coincidenti. Tutti i rami dell’espressione switch devono restituire valori dello stesso tipo; altrimenti il compilatore non accetterà il codice.
Errore n. 4: duplicazione dei valori case. Non è possibile indicare due volte lo stesso case — il compilatore segnalerà immediatamente un errore.
GO TO FULL VERSION