W3docs

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 oder enum-Namen verwenden — aber keine Variable oder einen Methodenaufruf. case x:, wobei x eine 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

java— editable, runs on the server

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.

Übungen

Übung
Was passiert in einem traditionellen Java-switch, wenn du break in einem case-Block weglässt?
Was passiert in einem traditionellen Java-switch, wenn du break in einem case-Block weglässt?
Was this page helpful?