Skip to main content
Entwickler Themen
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Java 21 (LTS)

Java 21 (September 2023) ist eine LTS-Version. Zwischen Java 18 und 21 sind wichtige Sprach- und Plattform-Features gereift: von Vorschauen (Preview/Incubator) hin zu finalen Features. Diese Seite fasst die wichtigsten Highlights zusammen und zeigt kurze Beispiele.

Highlights im Überblick

  • Virtual Threads (leichtgewichtige Threads) – Vorschau in 19/20, final in 21
  • Pattern Matching für switch – mehrere Vorschauen, final in 21
  • Record Patterns – Vorschau 19/20, final in 21
  • Sequenced Collections – neu in 21
  • String Templates – Vorschau in 21
  • Foreign Function & Memory API – mehrere Vorschauen bis 21
  • Structured Concurrency – Vorschau in 21
  • Generational ZGC – neu in 21
  • Praktische Tools/Defaults: Simple Web Server (18), „UTF-8 by default“ (18)

Java 18: Praktisches und Qualitätsverbesserungen

Simple Web Server (JEP 408)

Ein sehr einfacher, statischer Webserver für lokale Tests und Demos.

jwebserver --directory . --port 8000

Aufruf liefert statische Dateien aus dem aktuellen Verzeichnis aus.

UTF‑8 als Standard (JEP 400)

Seit Java 18 ist UTF‑8 die Standard-Charset-Plattform. Das reduziert Encoding-Fallen über Plattformen hinweg.


Java 19/20: Loom, Pattern Matching & FFM reifen in Vorschauen

Wesentliche Themen in 19 und 20 waren Vorschauen/Incubators, die in 21 finalisiert oder weitergeführt wurden:

  • Virtual Threads (Project Loom) – Vorschau in 19/20
  • Pattern Matching für switch – weitere Vorschauen
  • Record Patterns – Vorschau (19) und zweite Vorschau (20)
  • Foreign Function & Memory API – Vorschauen (19/20)
  • Structured Concurrency – Incubator/Preview
  • Vector API – fortgesetzter Incubator

Die folgenden Abschnitte zeigen die finalen Formen in Java 21.


Virtual Threads (Java 21 final)

Virtual Threads ermöglichen sehr viele nebenläufige Aufgaben mit minimalem Overhead – ideal für serverseitige I/O-lastige Workloads.

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class VirtualThreadsDemo {
  public static void main(String[] args) throws Exception {
    try (ExecutorService es = Executors.newVirtualThreadPerTaskExecutor()) {
      for (int i = 0; i < 1_000; i++) {
        int id = i;
        es.submit(() -> {
          System.out.println("Task " + id + " auf " + Thread.currentThread());
          // I/O-Operationen skalieren besonders gut
          Thread.sleep(10);
          return null;
        });
      }
    }
  }
}

Nutzen: kaum Blockierkosten pro Thread, einfache Migration von „klassischem“ Threading-Code.


Pattern Matching für switch (Java 21 final)

switch kann jetzt auf Muster matchen und Variablen binden, inklusive Guard-Clauses (when).

class SwitchPatternDemo {
  static String describe(Object o) {
    return switch (o) {
      case Integer i when i > 0 -> "Positive Zahl: " + i;
      case Integer i            -> "Nicht-positive Zahl: " + i;
      case String s  when s.isBlank() -> "Leerer String";
      case String s  -> "String (Länge=" + s.length() + ")";
      case null      -> "null";
      default        -> "Sonstiges: " + o.getClass().getSimpleName();
    };
  }
}

Nutzen: weniger instanceof/Casting, kompaktere Fallunterscheidungen.


Record Patterns (Java 21 final)

Record-Objekte lassen sich direkt per Muster zerlegen. Verschachtelte Muster werden unterstützt.

record Point(int x, int y) {}

class RecordPatternDemo {
  static int manhattan(Object o) {
    return switch (o) {
      case Point(int x, int y) -> Math.abs(x) + Math.abs(y);
      default -> 0;
    };
  }
}

Nutzen: sehr prägnante, ausdrucksstarke Destrukturierung in Kontrollfluss.


Sequenced Collections (Java 21)

Neue Interfaces wie SequencedCollection, SequencedSet und SequencedMap bieten definierte Reihenfolge-Operationen (getFirst, getLast, reversed …).

import java.util.*;

class SequencedDemo {
  public static void main(String[] args) {
    SequencedCollection<String> sc = new ArrayDeque<>();
    sc.addFirst("A");
    sc.addLast("B");
    System.out.println(sc.getFirst()); // A
    System.out.println(sc.getLast());  // B
    System.out.println(sc.reversed()); // Ansicht in umgekehrter Reihenfolge
  }
}

Nutzen: einheitliche API für Datenstrukturen mit Reihenfolge.


String Templates (Java 21 – Vorschau)

Saubere String-Interpolation mit Templates und Prozessoren.

// Vorschaubeispiel – erfordert Aktivierung der Preview-Features beim Kompilieren/Laufen
// javac --enable-preview --release 21 Demo.java
// java  --enable-preview Demo

import static java.lang.StringTemplate.STR;

class StringTemplatesDemo {
  public static void main(String[] args) {
    int x = 7;
    String s = STR."x = \{x}, x^2 = \{x * x}";
    System.out.println(s);
  }
}

Nutzen: sicherere, lesbarere String-Zusammensetzung als manuelles Konkatenieren oder String.format.


Foreign Function & Memory API (FFM) – Vorschau in 19–21

Die FFM-API ermöglicht Typsichere Interop mit „native“ Code (C-Bibliotheken) ohne JNI-Boilerplate sowie sichere Off-Heap-Speicherverwaltung.

Mini‑Beispiel (konzeptionell; reale Nutzung erfordert passende nativen Symbole):

// Preview-API; Kompilierung mit --enable-preview nötig
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;

class FFMDemo {
  public static void main(String[] args) {
    try (Arena arena = Arena.ofConfined()) {
      MemorySegment seg = arena.allocate(4); // 4 Bytes Off-Heap
      seg.setAtIndex(java.lang.foreign.ValueLayout.JAVA_INT, 0, 42);
      int v = seg.getAtIndex(java.lang.foreign.ValueLayout.JAVA_INT, 0);
      System.out.println(v); // 42
    }
  }
}

Nutzen: weniger JNI, klarere Speicherlebenszyklen, bessere Performance.


Structured Concurrency (Java 21 – Vorschau)

Vereinfacht die Koordination mehrerer Aufgaben, indem sie als Einheit behandelt werden.

// Preview-API
import java.util.concurrent.Callable;
import java.util.concurrent.StructuredTaskScope;

class StructuredConcurrencyDemo {
  String fetch() throws Exception {
    try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
      Callable<String> a = () -> expensiveCall("A");
      Callable<String> b = () -> expensiveCall("B");
      var fa = scope.fork(a);
      var fb = scope.fork(b);
      scope.join();
      scope.throwIfFailed();
      return fa.resultNow() + "," + fb.resultNow();
    }
  }

  static String expensiveCall(String id) throws InterruptedException {
    Thread.sleep(50);
    return id;
  }
}

Nutzen: robuster paralleler Code mit klaren Abbruch- und Fehlersemantiken.


Generational ZGC (Java 21)

ZGC erhält eine Generationen-Variante, die kurzlebige von langlebigen Objekten trennt und so Durchsatz und Pausenzeiten weiter verbessert.

Aktivierung über JVM-Flags, z. B.:

java -XX:+UseZGC -XX:+ZGenerational ...

Fazit

Mit Java 21 als LTS sind zentrale Themen wie Pattern Matching und Virtual Threads produktionsreif. Viele zuvor als Vorschau eingeführte Features sind konsolidiert; neue APIs (Sequenced Collections) und GC-Verbesserungen runden das Release ab. Projekte, die noch auf 17 LTS stehen, profitieren bei einem Upgrade vor allem von besserer Skalierbarkeit (Virtual Threads), prägnanterem Code (Pattern/Record Patterns, String Templates – sobald final) und moderneren Bibliotheken.