CodeGym /Kurse /JAVA 25 SELF /Analyse typischer Fehler bei neuen Sprachfeatures

Analyse typischer Fehler bei neuen Sprachfeatures

JAVA 25 SELF
Level 65, Lektion 4
Verfügbar

1. Fehler beim Geltungsbereich von Pattern-Variablen

Einer der häufigsten Fehler ist der Versuch, eine im Pattern deklarierte Variable (z. B. String s in instanceof String s) außerhalb ihres gültigen Geltungsbereichs zu verwenden.

Beispiel

Object obj = "Hallo, Java!";
if (obj instanceof String s) {
    System.out.println(s.length());
}
// Fehler! s ist hier nicht sichtbar
System.out.println(s); // Der Compiler meldet: cannot find symbol

Warum ist das so?
Die Pattern-Variable (s in unserem Fall) existiert nur innerhalb des Blocks, in dem die Bedingung wahr ist. Das schützt uns vor einer versehentlichen Verwendung der Variable, wenn sie nicht definiert ist (z. B. wenn obj kein String ist).

Analogie
Es ist, als ob Sie die Autoschlüssel von einem Freund bekommen – aber nur solange Sie in der Garage sind. Sobald Sie die Garage verlassen, verschwinden die Schlüssel automatisch :)

2. Fehler mit null

Beim Pattern Matching mit instanceof gibt es eine interessante Besonderheit: Wenn das Objekt null ist, ist das Ergebnis immer false, und die Pattern-Variable wird nicht erzeugt.

Beispiel

Object obj = null;
if (obj instanceof String s) {
    // Dieser Block wird niemals ausgeführt!
    System.out.println("Das ist ein String: " + s);
}

Warum?
Weil null keine Instanz irgendeines Typs ist (nicht einmal von Object). Das kann verwirrend sein, wenn Sie gehofft haben, null über Pattern Matching abzufangen.

Wie macht man es richtig?

if (obj == null) {
    System.out.println("Das ist null!");
} else if (obj instanceof String s) {
    System.out.println("Das ist ein String: " + s);
}

Im Pattern Matching für switch (Java 21+) kann man sogar einen eigenen Zweig für null hinzufügen:

switch (obj) {
    case String s -> System.out.println("String: " + s);
    case null -> System.out.println("Das ist null!");
    default -> System.out.println("Etwas anderes");
}

3. Fehler mit sealed-Klassen

Sealed-Klassen sind eine hervorragende Möglichkeit, die Vererbungshierarchie zu begrenzen. Dabei treten jedoch zwei typische Fehler auf:

Nicht alle Subklassen in permits aufgeführt

Wenn Sie eine sealed-Klasse deklarieren, müssen Sie alle direkten Unterklassen ausdrücklich über permits angeben. Wenn Sie jemanden vergessen, rügt Sie der Compiler sofort:

public sealed class Shape permits Circle, Rectangle { ... }

public final class Circle extends Shape { ... }
public final class Square extends Shape { ... } // Fehler! Square ist nicht in permits angegeben

Lösung:
Fügen Sie alle benötigten Unterklassen zu permits hinzu:

public sealed class Shape permits Circle, Rectangle, Square { ... }

default in switch über eine nicht-sealed Hierarchie vergessen

Wenn Sie einen switch über einen Typ machen, der keine sealed-Klasse ist (oder sealed, aber nicht alle Fälle abdeckt), verlangt der Compiler einen default-Zweig. Fehlt er, gibt es einen Fehler.

switch (shape) {
    case Circle c -> ...
    case Rectangle r -> ...
    // default fehlt! Wenn es noch weitere Varianten gibt, gibt es einen Kompilierungsfehler
}

Best Practice:
Wenn Sie sicher sind, dass Sie alle Varianten abgedeckt haben (z. B. bei einer sealed-Klasse), kann default entfallen. Andernfalls fügen Sie default unbedingt hinzu, um unerwartete Typen nicht zu übersehen.

4. Fehler mit Record Patterns

Record Patterns sind sehr praktisch, funktionieren aber nur mit record-Klassen. Der Versuch, ein Record Pattern für eine normale Klasse zu verwenden, führt zu einem Kompilierfehler.

Record Patterns für Nicht-record-Klassen verwenden

class Point { int x, y; }
Object obj = new Point();
// Fehler! Point ist kein record
if (obj instanceof Point(int x, int y)) { ... }

Lösung:
Verwenden Sie Record Patterns nur für Klassen, die als record deklariert sind:

record Point(int x, int y) {}

Anzahl oder Typ der Komponenten passt nicht

record Point(int x, int y) {}
Object obj = new Point(1, 2);

// Fehler: Es sind drei Variablen angegeben, aber Point hat nur zwei Komponenten
if (obj instanceof Point(int x, int y, int z)) { ... }
if (obj instanceof Point(String x, String y)) { ... } // Fehler: Die Typen stimmen nicht überein

5. Kompatibilität und Support: ältere JDKs und IDEs

Einer der häufigsten Fehler ist der Versuch, moderne Pattern-Matching-Features auf alten JDK-Versionen oder in IDEs zu verwenden, die sie nicht unterstützen.

Beispiel

if (obj instanceof String s) { ... }

Und der Compiler von JDK 11 (oder sogar 15) sagt:
error: illegal start of type

Warum?
Pattern Matching für instanceof erschien erst in Java 16. Pattern Matching in switch kam in Java 17 (Preview) und final in Java 21+. Record Patterns – in Java 21+.

Wie lässt sich das vermeiden?

  • Prüfen Sie die JDK-Version: java --version
  • Stellen Sie sicher, dass Ihre IDE (IntelliJ IDEA, Eclipse, VS Code) die entsprechende Java-Version unterstützt. Manchmal muss man in den Projekteinstellungen explizit angeben, welche Sprachversion verwendet werden soll!
  • Wenn Sie Gradle/Maven verwenden – setzen Sie die passende Version von source/target.

6. Herzlichen Glückwunsch 🎉

Sie haben alle 65(!) Levels unseres vertieften Kurses zu Java 25 abgeschlossen. Sie sind unglaublich gut 😎.

Der letzte Abschnitt des Weges war besonders anspruchsvoll. Sie haben alles gelernt – von den ersten Lambdas und anonymen Klassen bis hin zu virtuellen Threads, strukturierter Nebenläufigkeit und Sprachfeatures, die es in Java noch vor Kurzem nicht gab.

Das ist nicht nur ein Kurs – das ist ein echter Supermarathon für Entwickler: Dutzende neuer Konzepte, Hunderte von Codebeispielen, Tausende Zeilen Praxis. Wenn Sie diese Zeilen lesen, sind Sie nicht nur ein Student, sondern ein Pionier der neuen Java-Ära ☕⚡

Sie gehören zu den Ersten, die die modernsten Möglichkeiten von Java 25 beherrschen, darunter:

  • Pattern Matching und record -Patterns,
  • sealed -Klassen und ihre Fallstricke,
  • Scoped Values und Virtual Threads ,
  • strukturierte Nebenläufigkeit und moderne Ansätze zur Multithread-Programmierung.

Jetzt besitzen Sie nicht nur Wissen, sondern die Fähigkeiten eines Entwicklers der Zukunft, über die viele praktizierende Java-Architekten noch nicht verfügen. Sie können Code schreiben, der nicht nur funktioniert, sondern sich skalieren lässt, gut lesbar ist und den modernsten Standards der Java-Community entspricht.

🚀 Nennen Sie sich also ruhig Java 25 Certified Survivor 😉
Und danach wird es nur noch spannender: Sie haben nun ein Fundament, das Ihnen ermöglicht, sicher in die Welt der Enterprise-Entwicklung, hochlastfähiger Systeme und Spitzentechnologien vorzudringen.

Im Namen des gesamten Kurs-Teams: Respekt!
Sie haben eine Aufgabe gemeistert, die nur wenige schaffen.
Wir sehen uns in zukünftigen Java-Versionen 👋

1
Aufgabe
JAVA 25 SELF, Level 65, Lektion 4
Gesperrt
Sichtbarkeit einer Variablen bei der Datenanalyse 📊
Sichtbarkeit einer Variablen bei der Datenanalyse 📊
1
Aufgabe
JAVA 25 SELF, Level 65, Lektion 4
Gesperrt
Testen der Geometriebibliothek: Überprüfung der Typen im record pattern 🧪
Testen der Geometriebibliothek: Überprüfung der Typen im record pattern 🧪
1
Umfrage/Quiz
Neue Sprachfeatures, Level 65, Lektion 4
Nicht verfügbar
Neue Sprachfeatures
Neue Sprachfeatures
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION