Wie eine if/else-Anweisung ermöglicht es dir auch eine switch-Anweisung, den Ablauf des Programms zu ändern, indem du Code bedingt ausführst.
Der Unterschied ist, dass eine switch-Anweisung den Wert eines primitiven Ausdrucks oder eines String-Ausdrucks nur mit vordefinierten konstanten Werten vergleichen kann.
Bei der Verwendung einer switch-Anweisung sind einige Schlüsselwörter nützlich.
switch: Mit diesem Schlüsselwort kannst du die Struktur der switch-Anweisung festlegen.
Darauf folgt der Ausdruck oder die Variable, welche das Ergebnis verändert.case: Dieses verwendest du, um die verschiedenen Möglichkeiten für das Ergebnis anzugeben.break: Das Schlüsselwort break ist sehr nützlich, um die Ausführung der switch-Anweisung am Ende des gewünschten Ablaufs zu stoppen.
Wenn du es vergisst, läuft das Programm weiter und kann zu unerwarteten Ergebnissen führen.default: Wie der Name schon sagt, verwendest du es als Standardergebnis, wenn kein anderer case zum Ergebnis deines Ausdrucks passt.In ihrer einfachsten Form prüfen sie einen primitiven Ausdruck oder einen String-Ausdruck und treffen anhand seines Werts eine Entscheidung. Zum Beispiel:
String direction = getDirection();
switch (direction) {
case "left":
goLeft();
break;
case "right":
goRight();
break;
default:
// otherwise
markTime();
break;
}
Ab Java 14 (zuvor in Java 12 und 13 als Vorschau verfügbar) ist es möglich, die „erweiterte“ switch-Implementierung zu verwenden.
Du kannst einem einzelnen case mehrere Werte zuweisen.
In der traditionellen switch-Anweisung kannst du Fall-through verwenden. Im folgenden Beispiel führen case 1 und case 3 denselben Code aus.
Das liegt daran, dass case 1 das Schlüsselwort break nicht verwendet.
switch (number) {
case 1:
case 3:
// do same stuff
break;
case 2:
// do different stuff
break;
// (...)
}
Im erweiterten switch expression kannst du einem case direkt mehrere Werte zuweisen.
Schau dir das folgende Beispiel an:
switch (number) {
case 1, 3:
// do stuff
break;
case 2:
// do other stuff
break;
// (...)
}
Du kannst jetzt sowohl switch-statement als auch switch expression schreiben.
Was ist der Unterschied?
Grundsätzlich erwartet eine Anweisung eine strikte Logik, während ein Ausdruck einen Wert zurückgeben kann.
Statt:
String result = "";
switch (expression) {
case "bob":
result = "bob";
break;
// (...)
}
Kannst du Folgendes schreiben:
String result = switch (expression) {
case "bob":
yield "bob";
// (...)
}
Das yield funktioniert wie ein return, nur dass es für switch-Ausdrücke gedacht ist.
Da yield den Ausdruck beendet, wird break hier nicht benötigt.
Ein weiterer Unterschied zwischen switch statements und switch expressions: In switch expressions musst du alle Fälle abdecken.
Entweder mit einem case für alle möglichen Werte oder mit einem default-Fall.
Du kannst -> statt : verwenden.
Mit -> kannst du das Schlüsselwort break weglassen.
Beide Schreibweisen sind möglich, aber innerhalb einer switch-Anweisung musst du dich auf eine einzige festlegen.
switch(expression) {
case 1 -> yield "one"
case 2 -> yield "two"
default: yield "other number" // Removing this will result in a compile error
}
Der Gültigkeitsbereich.
Ein traditionelles switch kann aufgrund seines Gültigkeitsbereichs zu unerwartetem Verhalten führen, da es für das gesamte switch nur einen Gültigkeitsbereich gibt.
switch(expression) {
case 1:
String message = "something";
break;
case 2:
String message = "anything";
break;
// (...)
}
Dieses Beispiel funktioniert nicht, weil message zweimal im switch deklariert wird.
Es ließe sich so lösen:
switch (expression) {
case 1: {
String message = "something";
break;
}
case 2: {
String message = "anything";
break;
}
// (...)
}
Da die {} den Gültigkeitsbereich des case abgrenzen.
Das ist allerdings nicht intuitiv, weil die {} nicht verpflichtend sind.
Wenn du jedoch die neue ->-Notation verwendest, muss darauf entweder eine einzelne Anweisung bzw. ein einzelner Ausdruck, eine throw-Anweisung oder ein {}-Block folgen.
Keine Verwirrung mehr!
Mehr Informationen zum erweiterten switch findest du in diesem Artikel und diesem hier, sowie in der offiziellen Oracle-Dokumentation.
Außerdem wurde in Java 21 ein Feature namens Guarded Patterns hinzugefügt, mit dem du Prüfungen direkt im case-Label vornehmen kannst.
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";
};
Mehr Informationen zum switch-Ausdruck in Java 21 findest du in diesem Blogbeitrag