Java switch-Anweisung
Verwende die switch-Anweisung in Java mit case-Labels, break, default und Fall-Through-Verhalten.
Wenn du einen einzelnen Wert mit vielen Möglichkeiten vergleichen musst, wird eine lange if/else if-Kette schnell unübersichtlich. Die switch-Anweisung ist Javas kompakte Alternative — den Wert einmal lesen, zum passenden case springen, dessen Block ausführen.
Grundlegende Syntax
switch (value) {
case label1:
// body
break;
case label2:
// body
break;
default:
// body
break;
}Ein kleines Beispiel:
int day = 3;
switch (day) {
case 1:
System.out.println("Monday");
break;
case 2:
System.out.println("Tuesday");
break;
case 3:
System.out.println("Wednesday");
break;
default:
System.out.println("Other");
break;
}Der switch springt zu case 3:, gibt Wednesday aus, trifft auf break und beendet die Ausführung.
Das break ist unverzichtbar
Ohne break fällt die Ausführung durch zum nächsten case — auch wenn dessen Label nicht übereinstimmt. Das ist ein bewusstes Merkmal des C-Stil-switch, aber es ist die Ursache unzähliger Fehler in Java-Code:
switch (day) {
case 1:
System.out.println("Monday");
// no break!
case 2:
System.out.println("Tuesday");
break;
}Wenn day == 1 ist, werden sowohl Monday als auch Tuesday ausgegeben. Füge immer break hinzu, es sei denn, du möchtest bewusst Fall-Through verwenden.
Absichtliches Fall-Through
Manchmal ist Fall-Through genau das, was du willst — mehrere Labels unter demselben Block gruppieren:
switch (day) {
case 1:
case 2:
case 3:
case 4:
case 5:
System.out.println("Weekday");
break;
case 6:
case 7:
System.out.println("Weekend");
break;
}Wenn du das absichtlich tust, füge einen // fall through-Kommentar hinzu, damit Reviewer nicht denken, du hast ein break vergessen. (Die neue switch-Ausdrucks-Syntax — behandelt im nächsten Kapitel — behebt dieses Problem vollständig.)
Was kann ein switch-Wert sein?
Ein traditioneller switch akzeptiert:
- Alle Integer-Typen:
byte,short,int,char - Ihre geboxter Wrapper:
Byte,Short,Integer,Character String(seit Java 7)enum-Konstanten
Nicht erlaubt: long, float, double, boolean oder beliebige Objekte. Für diese verwende if/else.
String role = "admin";
switch (role) {
case "admin":
System.out.println("Full access");
break;
case "editor":
System.out.println("Write access");
break;
case "viewer":
System.out.println("Read access");
break;
default:
System.out.println("No access");
break;
}Der String-Vergleich in einem switch verwendet String.equals-Semantik — Groß- und Kleinschreibung wird unterschieden. Eine besondere Fallstrick: Ein switch auf einen String (oder einen geboxter/enum-Wert), der null ist, wirft eine NullPointerException. Prüfe auf null vor dem switch oder behandle es in einer Bedingung:
if (role == null) {
System.out.println("No role");
} else {
switch (role) {
case "admin":
System.out.println("Full access");
break;
// ...
}
}default — der Auffangfall
default wird ausgeführt, wenn kein case übereinstimmt. Es ist nicht erforderlich, aber ein default einzufügen ist gute Praxis; es macht das Verhalten bei unerwarteten Werten explizit.
default muss nicht am Ende stehen. Konventionell steht es unten, aber der Compiler akzeptiert es überall — die Ausführung fällt durch es hindurch wie bei jedem anderen case, wenn du break vergisst.
Regeln zum Merken
Einige vom Compiler erzwungene Regeln überraschen Entwickler:
- Case-Labels müssen Compile-Zeit-Konstanten sein. Du kannst Literale (
case 3:),final-Konstanten oderenum-Namen verwenden — aber keine Variable oder einen Methodenaufruf.case x:, wobeixeine nicht-finale Variable ist, lässt sich nicht kompilieren. - Labels müssen eindeutig sein. Zwei
case 3:-Einträge im selben switch sind ein Kompilierfehler. - Alle cases teilen einen gemeinsamen Geltungsbereich. Eine in einem case deklarierte Variable ist in den anderen sichtbar, was zu Konflikten führen kann. Umschließe einen case-Block mit
{ }-Klammern, wenn du eine lokale Variable benötigst, die nur auf diesen case beschränkt ist:
switch (day) {
case 1: {
int hours = 8;
System.out.println(hours);
break;
}
case 2:
// `hours` is not visible here
break;
}Switching auf enum
enum und switch sind ein natürliches Paar. Innerhalb eines switch auf einen enum-Wert musst du den Konstantennamen nicht qualifizieren:
enum Status { PENDING, ACTIVE, DONE }
Status s = Status.ACTIVE;
switch (s) {
case PENDING: // not Status.PENDING
System.out.println("Waiting...");
break;
case ACTIVE:
System.out.println("In progress");
break;
case DONE:
System.out.println("Finished");
break;
}Ein ausgearbeitetes Beispiel
Was kommt als Nächstes
Java 14 hat switch-Ausdrücke eingeführt, die einen Wert zurückgeben, Fall-Through eliminieren und Multi-Label-cases unterstützen — moderner Java-Code bevorzugt diese, wenn Java 14 oder neuer als Ziel verwendet wird.