Java 17 (LTS)
Java 17 (September 2021) ist eine LTS-Version. Zwischen Java 12 und 17 sind viele praxisrelevante Sprach- und Plattform-Features hinzugekommen. Diese Seite fasst die wichtigsten Highlights zusammen und zeigt kurze Beispiele.
- Switch-Expressions (prägnante
switch-Ausdrücke) – Vorschau in 12/13, final in 14 - Text Blocks (mehrzeilige Strings) – Vorschau 13/14, final in 15
- Records (datengetriebene Klassen) – Vorschau 14/15, final in 16
- Pattern Matching für
instanceof– Vorschau 14/15, final in 16 - Sealed Classes (abgeschlossene Vererbung) – Vorschau 15/16, final in 17
- Pattern Matching für
switch– Vorschau in 17 - Hilfreiche NullPointerExceptions (bessere Fehlermeldungen) – 14
- Plattform-/Tools-Highlights: ZGC & Shenandoah als produktionsreife GCs (15),
jpackage(16), Unix-Domain-Sockets (16), Vector API (Incubator, 16)
Mit Switch-Expressions lässt sich switch als Ausdruck verwenden, der einen Wert zurückgibt. Außerdem gibt es die schlanke Pfeilsyntax und yield für komplexere Zweige.
Beispiel (finale Syntax ab Java 14):
class DemoSwitch {
static String dayType(int day) {
return switch (day) {
case 1, 2, 3, 4, 5 -> "Werktag";
case 6, 7 -> "Wochenende";
default -> throw new IllegalArgumentException("Unerwarteter Tag: " + day);
};
}
}
Mit Block und yield:
class DemoYield {
static String parity(int n) {
return switch (n % 2) {
case 0 -> {
String s = "gerade";
yield s;
}
default -> "ungerade";
};
}
}
Nutzen: weniger Boilerplate, keine break-Fallen, switch als Ausdruck.
Text Blocks sind mehrzeilige String-Literale, die Lesbarkeit von eingebetteten Texten (JSON, SQL, HTML) verbessern.
class DemoTextBlocks {
public static void main(String[] args) {
String json = """
{
"name": "Max",
"age": 28
}
""";
System.out.println(json);
}
}
Vorteile: automatische Zeilenumbrüche, einfache Einrückungen, weniger Escape-Sequenzen. Methoden wie stripIndent()/indent() helfen zusätzlich bei der Formatierung (über String-API).
Records sind kompakte, unveränderliche, datenfokussierte Klassen mit automatisch generierten equals, hashCode und toString.
record Person(String name, int age) {}
class DemoRecord {
public static void main(String[] args) {
var p = new Person("Anna", 30);
System.out.println(p.name()); // "Anna"
System.out.println(p); // Person[name=Anna, age=30]
}
}
Mit zusätzlicher Validierung:
record Range(int start, int end) {
public Range {
if (start > end) throw new IllegalArgumentException("start > end");
}
}
Nutzen: deutlich weniger Boilerplate für DTOs und Value-Objekte.
Vereinfacht typische instanceof-Prüfungen mit anschließender Typumwandlung.
Vorher:
class BeforeInstanceofPattern {
public static void main(String[] args) {
Object obj = "Hallo";
if (obj instanceof String) {
String s = (String) obj;
System.out.println(s.toUpperCase());
}
}
}
Mit Pattern Matching:
class WithInstanceofPattern {
public static void main(String[] args) {
Object obj = "Hallo";
if (obj instanceof String s) {
System.out.println(s.toUpperCase());
}
}
}
Nutzen: weniger Casting, klarere und sicherere Kontrollflüsse.
Mit Sealed Classes lässt sich explizit einschränken, welche Klassen/Interfaces eine Klasse erweitern oder implementieren dürfen. Das macht Hierarchien ausdrücklicher und erleichtert Exhaustiveness-Checks.
sealed interface Shape permits Circle, Rectangle {}
final class Circle implements Shape {
final double r;
Circle(double r) { this.r = r; }
}
final class Rectangle implements Shape {
final double w, h;
Rectangle(double w, double h) { this.w = w; this.h = h; }
}
Exhaustive switch (in Kombination mit Records/Pattern Matching besonders stark):
class ShapeUtil {
static double area(Shape s) {
return switch (s) {
case Circle c -> Math.PI * c.r * c.r;
case Rectangle r -> r.w * r.h;
};
}
}
Erweitert switch um Muster (z. B. Typmuster) und Guard-Conditions. In 17 als Preview verfügbar.
class DemoSwitchPattern { // Preview-Feature in 17
static String describe(Object o) {
return switch (o) {
case null -> "null";
case String s -> "String: " + s;
case Integer i -> "Zahl: " + i;
default -> "etwas anderes";
};
}
}
Nutzen: Ausdrucksstarke, sichere Verzweigungen ohne verschachtelte if-Ketten.
Seit Java 14 enthalten NPEs mehr Details darüber, welcher Teil eines Ausdrucks null war. Das beschleunigt die Fehlersuche.
Beispielausgabe (verkürzt):
Exception in thread "main" java.lang.NullPointerException:
Cannot invoke "Address.city()" because "user.address()" is null
Aktiv per Default; kann über JVM-Flags beeinflusst werden.
- ZGC (JEP 377) und Shenandoah (JEP 379) als produktionsreife, niedrige Latenz-GCs in Java 15
jpackage(JEP 392, Java 16): nativer Installer/Bundle-Erzeuger für Anwendungen- Unix-Domain-Sockets (JEP 380, Java 16): effizientere lokale IPC
- Vector API (JEP 338, Incubator, Java 16): portable Vektor-Operationen für numerische Workloads
Diese Features sind besonders für Performance, Deployment und Systemintegration relevant.
- 12: Switch-Expressions (Preview)
- 13: Text Blocks (Preview), Switch-Expressions (2. Preview)
- 14: Switch-Expressions (final), Records (Preview), Pattern Matching
instanceof(Preview), hilfreiche NPEs - 15: Text Blocks (final), Records (2. Preview), Pattern Matching
instanceof(2. Preview), Sealed Classes (Preview), ZGC & Shenandoah produktionsreif - 16: Records (final), Pattern Matching
instanceof(final), Sealed Classes (2. Preview),jpackage, Unix-Domain-Sockets, Vector API (Incubator) - 17 (LTS): Sealed Classes (final), Pattern Matching für
switch(Preview), diverse JVM/Library-Verbesserungen