W3docs

Java Switch-Ausdrücke

Moderne Switch-Ausdrücke in Java mit Pfeil-Syntax, yield und erschöpfendem Pattern Matching.

Java 14 hat Switch-Ausdrücke als standardisiertes Sprachmerkmal eingeführt. Sie bauen auf der traditionellen switch-Anweisung auf und bieten drei wesentliche Verbesserungen: Sie liefern einen Wert, verwenden eine sauberere Pfeil-Syntax und machen Fall-Through unmöglich. Wenn Sie Java 14 oder neuer verwenden, sollten Sie Switch-Ausdrücke bevorzugen.

Dieses Kapitel behandelt die Pfeil-Syntax, das Schlüsselwort yield für Blockkörper, Vollständigkeitsprüfung und das typbasierte Pattern Matching, das in Java 21 standardisiert wurde. Am Ende wissen Sie, wann Sie einen Switch-Ausdruck einer if/else-Kette vorziehen sollten.

Anweisung vs. Ausdruck

Das traditionelle switch ist eine Anweisung: Es führt etwas aus (Seiteneffekte), liefert aber keinen Wert. Ein Switch-Ausdruck wertet zu einem Wert aus, den Sie zuweisen, zurückgeben oder an eine Methode übergeben können. Dieser eine Unterschied treibt alles andere auf dieser Seite an — weil das Ergebnis verwendet wird, kann der Compiler verlangen, dass jeder Zweig einen Wert liefert und kein Eingabewert unbehandelt bleibt.

Pfeil-Syntax

String day = "TUE";

String label = switch (day) {
  case "MON", "TUE", "WED", "THU", "FRI" -> "weekday";
  case "SAT", "SUN" -> "weekend";
  default -> "unknown";
};

Drei Dinge sind zu beachten:

  1. Das gesamte switch ist ein Ausdruck — es wertet zu einem Wert aus, den Sie zuweisen können (beachten Sie das abschließende ;).
  2. Jeder Case verwendet -> statt :. Die rechte Seite ist eine Anweisung oder ein Ausdruck.
  3. Mehrere Labels sind in einem Case erlaubt, durch Komma getrennt. Kein break, kein Fall-Through.

Blockkörper mit yield

Wenn ein Case mehrere Anweisungen benötigt, verwenden Sie einen Block — und innerhalb des Blocks geben Sie den Wert mit yield zurück:

int score = 78;

String grade = switch (score / 10) {
  case 10, 9 -> "A";
  case 8 -> "B";
  case 7 -> {
    System.out.println("close to B");
    yield "C";
  }
  case 6 -> "D";
  default -> "F";
};

yield ist wie return, aber für den Switch-Ausdruck — es setzt den Wert dieses Switch und verlässt den Case. (Verwechseln Sie es nicht mit return, das die umgebende Methode verlassen würde.)

Sie benötigen yield nur innerhalb eines Blocks ({ ... }). Ein einzeiliger Case wie case 8 -> "B"; gibt seinen Wert bereits direkt zurück, weshalb ein yield dort ein Compilerfehler wäre.

Info

yield ist ein kontextuelles Schlüsselwort: Es wirkt nur als Schlüsselwort innerhalb eines Switch-Blocks. Code, der yield vor Java 14 als Variablen- oder Methodennamen verwendet hat, kompiliert weiterhin, sodass die Einführung von Switch-Ausdrücken vorhandene Bezeichner nie beeinträchtigt.

Anweisungen funktionieren weiterhin

Sie können die Pfeil-Syntax auch für Seiteneffekte verwenden — in diesem Fall handelt es sich um eine Anweisung, nicht um einen Ausdruck:

switch (day) {
  case "MON", "TUE", "WED", "THU", "FRI" -> System.out.println("weekday");
  case "SAT", "SUN" -> System.out.println("weekend");
  default -> System.out.println("unknown");
}

Der Vorteil gegenüber der alten Form: kein break, keine Fall-Through-Fehler, dazu die oben beschriebenen Multi-Label-Cases.

Vollständigkeit

Wenn ein Switch-Ausdruck einer Variablen zugewiesen wird, verlangt der Compiler, dass jede mögliche Eingabe einen Wert liefert. Für ein enum bedeutet das, entweder alle Konstanten abzudecken oder ein default bereitzustellen:

enum Status { PENDING, ACTIVE, DONE }

Status s = Status.ACTIVE;

String label = switch (s) {
  case PENDING -> "waiting";
  case ACTIVE  -> "running";
  case DONE    -> "complete";
};   // no default needed — all enum values are covered

Wenn Sie später eine neue Konstante zum Enum hinzufügen und vergessen, den Switch zu aktualisieren, wird der Compiler Sie darauf hinweisen. Das ist eine starke Korrektheitsgarantie, die Sie mit if/else nicht erhalten.

Pattern Matching (Java 21+)

Java 21 hat Pattern Matching für switch als Standardfunktion eingeführt. Sie können auf den Typ eines Werts prüfen und ihn innerhalb des Cases an eine typisierte Variable binden:

Object o = 42;

String description = switch (o) {
  case Integer i when i < 0 -> "negative int: " + i;
  case Integer i             -> "non-negative int: " + i;
  case String s              -> "string of length " + s.length();
  case null                  -> "null value";
  default                    -> "something else";
};

Die when-Klausel ist ein Guard — sie schränkt einen Case mit einer booleschen Bedingung weiter ein. Dies ersetzt viele instanceof-Ketten und passt gut zu den umfassenderen Pattern-Matching-Funktionen.

Zwei Regeln sind zu beachten:

  • Ein traditionelles switch wirft bei einem null-Selektor eine NullPointerException. Ein Pattern-Switch kann einen expliziten case null enthalten — ohne ihn wird ein null immer noch ausgelöst. Dass null den Switch still erreicht, kann nicht mehr übersehen werden.
  • Cases werden von oben nach unten geprüft, also von spezifischsten zu allgemeinsten ordnen. Der bewachte case Integer i when i < 0 muss vor dem einfachen case Integer i stehen, sonst würde der unbewachte Case jeden Integer zuerst verarbeiten.

Ein praktisches Beispiel

java— editable, runs on the server

Wie geht es weiter

Wir haben Bedingungen behandelt. Als nächstes kommen die Schleifen: Die while-Schleife ist die einfachste davon.

Übungen

Übung
Welches Schlüsselwort gibt den Wert in einem Switch-Ausdruck mit Pfeil-Syntax und Blockkörper zurück?
Welches Schlüsselwort gibt den Wert in einem Switch-Ausdruck mit Pfeil-Syntax und Blockkörper zurück?
Was this page helpful?