unnamed variables and patternsunnamed variables and patterns
HappyCoders Glasses

Unbenannte Variablen und Patterns in Java

Sven Woltmann
Sven Woltmann
Aktualisiert: 7. Juni 2026

In diesem Artikel erfährst du:

  • Was ist eine unbenannte Variable, und welchen Zweck erfüllt sie?
  • Was sind unbenannte Patterns und unbenannte Pattern-Variablen, und welchen Zweck erfüllen sie?
  • Wie kann man Switch-Ausdrücke mit unbenannten Pattern-Variablen prägnanter schreiben?

Unbenannte Variablen und Patterns wurden in Java 21 im Rahmen von Project Amber als Preview-Feature eingeführt. In Java 22 wurden sie finalisiert.

Unbenannte Variablen

Oft kommt es vor, dass wir eine Variable definieren müssen, die wir gar nicht benötigen. Hier zwei Beispiele, die du wahrscheinlich kennst:

Beispiel 1: Exceptions – hier wird e nicht verwendet:

try {
    int number = Integer.parseInt(string);
} catch (NumberFormatException e) {
    System.err.println("Not a number");
}Code-Sprache: Java (java)

Beispiel 2: Map.computeIfAbsent() – hier wird k nicht verwendet:

map.computeIfAbsent(key, k -> new ArrayList<>()).add(value);Code-Sprache: Java (java)

Ab Java 22 (bzw. ab Java 21 mit aktivierten Preview-Features) müssen wir solche Variablen nicht mehr benennen, sondern dürfen (wie in anderen Programmiersprachen lange üblich) stattdessen den Unterstrich (_) verwenden:

Hier das Exception-Beispiel mit unbenannter Variable:

try {
    int number = Integer.parseInt(string);
} catch (NumberFormatException _) {
    System.err.println("Not a number");
}Code-Sprache: Java (java)

Und das computeIfAbsent()-Beispiel:

map.computeIfAbsent(key, _ -> new ArrayList<>()).add(value);Code-Sprache: Java (java)

Bei einer Exception mag man sich über das Für und Wider einer unbenannten Variable streiten. Wir sind daran gewöhnt, eine Exception mit „e“ zu bezeichnen, bzw. unsere IDE das automatisch machen zu lassen.

Bei computeIfAbsent() hingegen habe ich mir immer Gedanken darüber gemacht, wie ich die nicht benötigte Variable benennen soll. Manchmal wurde es ein k (für „key“), manchmal ein ignored und manchmal ein __ (doppelter Unterstrich¹). Hier ist die unbenannte Variable eine große Hilfe.

¹ Der einfache Unterstrich war seit Java 9 in Vorbereitung auf genau dieses Feature nicht mehr erlaubt.

catch-Blöcke und Lambda-Parameter sind aber nicht die einzigen Stellen, an denen der Unterstrich hilft. Sehen wir uns die weiteren Einsatzorte an.

Die Schleifenvariable in einer for-Schleife

Manchmal interessiert uns an einer for-Schleife nur, wie oft etwas passiert – nicht, womit. Ein Beispiel: Wir wollen zählen, wie viele Elemente ein Iterable enthält. Da Iterable keine size()-Methode hat, müssen wir die Elemente per Schleife durchzählen – und dafür eine Schleifenvariable benennen, die wir gar nicht brauchen:

int count = 0;
for (Order order : orders) {
    count++;
}Code-Sprache: Java (java)

Die Variable order brauchen wir nicht – also ersetzen wir sie durch den Unterstrich:

int count = 0;
for (Order _ : orders) {
    count++;
}Code-Sprache: Java (java)

Lokale Variablen, deren Wert wir nicht brauchen

Auch eine ganz normale lokale Variable dürfen wir unbenannt lassen – etwa dann, wenn uns nur der Seiteneffekt eines Methodenaufrufs interessiert. Stell dir vor, wir entnehmen drei Elemente aus einer Queue, benötigen aber nur die ersten beiden:

while (queue.size() >= 3) {
    var first  = queue.remove();
    var second = queue.remove();
    var _      = queue.remove(); // entfernt das dritte Element, das wir nicht brauchen
    process(first, second);
}Code-Sprache: Java (java)

Ressourcen in try-with-resources

Ein try-with-resources-Block schließt seine Ressource automatisch – auch dann, wenn wir sie im Block gar nicht direkt ansprechen. Ein typisches Beispiel ist ein Lock, das wir nur halten, aber nicht aufrufen wollen:

try (var _ = lock.acquire()) {
    // kritischer Abschnitt – die Ressource wird beim Verlassen automatisch freigegeben
}Code-Sprache: Java (java)

So machst du sichtbar: Die Ressource ist wegen ihres Seiteneffekts wichtig (öffnen und schließen), aber im Block greifen wir nicht auf sie zu.

Unbenannte Patterns und Pattern-Variablen

Das Feature heißt allerdings nicht „Unnamed Variables“, sondern „Unnamed Variables & Patterns“ und hat somit noch einiges mehr zu bieten – und zwar bei den in Java 21 finalisierten Features Record Patterns und Pattern Matching for Switch.

Die Variable y wird im „then-Block“ des folgenden Code-Beispiels nicht benötigt:

if (object instanceof Position(int x, int y)) {
    System.out.println("object is a position, x = " + x);
}Code-Sprache: Java (java)

Auch hier können wir deswegen y durch einen Unterstrich ersetzen:

if (object instanceof Position(int x, int _)) {
    System.out.println("object is a position, x = " + x);
}Code-Sprache: Java (java)

Das nennt sich dann „unbenannte Pattern-Variable“.

Wir können sogar noch einen Schritt weitergehen und das komplette Teil-Pattern int y durch einen Unterstrich ersetzen:

if (object instanceof Position(int x, _)) {
    System.out.println("object is a position, x = " + x);
}Code-Sprache: Java (java)

Das nennt sich dann „unbenanntes Pattern“.

Im vorigen Beispiel hat das noch keine große Auswirkung; bei verschachtelten Patterns hingegen lässt sich damit eine Menge Platz sparen. Im folgenden Beispiel verwenden wir nur die Variablen x1 und y1, während x2 und y2 unbenutzt sind:

if (object instanceof Path(Position(int x1, int y1), Position(int x2, int y2))) {
    System.out.printf("object is a path starting at x = %d, y = %d%n", x1, y1);
}Code-Sprache: Java (java)

Hier können wir das komplette zweite Position-Pattern durch den Unterstrich ersetzen:

if (object instanceof Path(Position(int x1, int y1), _)) {
    System.out.printf("object is a path starting at x = %d, y = %d%n", x1, y1);
}Code-Sprache: Java (java)

Das stellt doch eine deutliche Verbesserung dar!

Unbenannte Pattern-Variablen und Pattern Matching for Switch

Hier ein Beispiel mit nicht verwendeten Variablen bei Pattern Matching for Switch:

switch (obj) {
    case Byte    b -> System.out.println("Integer number");
    case Short   s -> System.out.println("Integer number");
    case Integer i -> System.out.println("Integer number");
    case Long    l -> System.out.println("Integer number");

    case Float  f -> System.out.println("Floating point number");
    case Double d -> System.out.println("Floating point number");

    default -> System.out.println("Not a number");
}Code-Sprache: Java (java)

Auch hier dürfen wir alle Variablennamen durch Unterstriche ersetzen:

switch (obj) {
    case Byte    _ -> System.out.println("Integer number");
    case Short   _ -> System.out.println("Integer number");
    case Integer _ -> System.out.println("Integer number");
    case Long    _ -> System.out.println("Integer number");

    case Float  _ -> System.out.println("Floating point number");
    case Double _ -> System.out.println("Floating point number");

    default -> System.out.println("Not a number");
}Code-Sprache: Java (java)

Wir können sogar noch einen Schritt weitergehen und alle Fälle mit gleichen Aktionen zusammenfassen:

switch (obj) {
    case Byte _, Short _, Integer _, Long _ -> System.out.println("Integer number");
    case Float _, Double _                  -> System.out.println("Floating point number");

    default -> System.out.println("Not a number");
}Code-Sprache: Java (java)

Und das ist – neben der prägnanteren Schreibweise – der zweite große Vorteil der unbenannten Pattern-Variable! Mit benannten Variablen wäre das nämlich nicht möglich gewesen. Der folgende Code ist nicht gültig:

switch (obj) {
    // Not allowed!          
    case Byte b, Short s, Integer i, Long l -> System.out.println("Integer number");
    case Float f, Double d                  -> System.out.println("Floating point number");

    default -> System.out.println("Not a number");
}Code-Sprache: Java (java)

Dieser Code führt zu folgendem Compilerfehler:

error: illegal fall-through from a pattern
    case Byte b, Short s, Integer i, Long l -> System.out.println("Integer number");
               ^Code-Sprache: Klartext (plaintext)

Der entscheidende Unterschied ist, dass auf benannte Variablen von nachfolgendem Code aus zugegriffen werden kann, während auf unbenannte Variablen nicht zugegriffen werden darf. Da der Compiler nicht weiß, welches Pattern zur Laufzeit matchen wird, weiß er auch nicht, auf welche der Variablen b, s, i und l zugegriffen werden darf. Daher lässt er pro Fall nur eine benannte Variable, aber beliebig viele unbenannte Variablen zu.

Fazit

Unbenannte Variablen und Patterns lösen ein kleines, aber alltägliches Ärgernis: Wir müssen immer wieder Variablen deklarieren, die wir gar nicht verwenden – die Exception im catch-Block, den Key in computeIfAbsent(), die Schleifenvariable beim bloßen Zählen.

Mit dem Unterstrich zeigst du explizit, dass eine Variable bewusst ungenutzt bleibt. Dein Code wird prägnanter und gleichzeitig aussagestärker.

Zudem kannst du mehrere case-Labels mit demselben Code zusammenfassen, was nur mit unbenannten Pattern-Variablen funktioniert, nicht mit benannten.

Unnamed Variables & Patterns werden in JDK Enhancement Proposal 456 definiert.

Java-Schulungen
(online oder vor Ort)
»