Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

Java 21 im Ãœberblick

Neue Features

Die folgenden Features befinden sich ab Java 21 offiziell im JDK und sind uneingeschränkt nutzbar.

JEP-444: Virtual Threads

Nachdem sie bereits in den letzten beiden Releases als Preview-Feature vorhanden waren, sind die Virtual Threads jetzt offiziell in Java angekommen. Sie sind wohl eine der bemerkenswertesten Neuerungen in Java, die sich guten Gewissens in die Liste mit Generics, Lambdas & Streams oder dem Modulsystem einreihen dürfen.

Bisher war jeder Thread in Java an einen Betriebssystems-Thread gebunden. Wegen der dadurch benötigten Ressourcen ist die Anzahl dieser klassischen sogenannten „Platform threads“ begrenzt. Virtual Threads sind leichtgewichtige Threads, von denen es sehr viele geben kann (theoretisch Millionen), und die auf nur wenigen Platform threads, sogenannten carrier threads, laufen.

Für Entwickler ist das Verwenden von Virtual Threads sehr einfach, da sie genau wie Platform threads über die Klasse java.lang.Thread genutzt Werden. Lediglich in der Erzeugung der Threads gibt es Unterschiede, der Rest passiert „unter der Haube“.

Einen virtuellen Thread kann man beispielsweise wie folgt starten:

Zudem gibt es nun die Möglichkeit, einen ExecutorService zu erzeugen, der jeden ihm übergebenen Task in einem neuen Virtual Thread ausführt:

Virtuelle Threads eignen sich am besten für die Ausführung von Tasks, die die meiste Zeit über blockieren, weil sie z.B. auf den Abschluss von I/O-Operationen warten. Für lang laufende CPU-intensive Operationen dagegen bringen sie wenig Mehrwert.

JEP-441: Pattern Matching für switch

Bereits in Java 16 wurde Pattern Matching für instanceof eingeführt (JEP-394), welches das Casten nach der Prüfung auf einen bestimmten Typ überflüssig macht:

Ab Java 21 ist Pattern Matching auch in Switch-Statements sowie Switch-Ausdrücken möglich:

Neben einer Prüfung auf den Typ können auch zusätzliche Bedingungen angegeben werden:

Die Prüfung auf Integer ohne when-Bedingung muss am Schluss stehen – sie matcht nur dann, wenn die beiden vorangehenden Prüfungen nicht zutreffen. Würde sie ganz vorne stehen, würde sie die anderen beiden Prüfungen „überschatten“; in diesem Fall gäbe es einen Compilefehler.

Hätte obj in der Switch-Anweisung oben den Wert null, würde eine NullPointerException geworfen (dies war auch bisher schon der Fall). Um diesen Fall abzufangen, kann nun das null-Pattern genutzt werden:

JEP-440: Record Patterns

Hiermit können Patterns auch auf Records angewendet werden sowie Records „dekonstruiert“ werden. Gegeben sei ein Record „Pair“ mit zwei Werten von unterschiedlichen generischen Typen:

Nun lässt sich via Pattern Matching die gewünschte Typ-Kombination herausfiltern und mit den extrahierten Werten arbeiten:

Selbst verschachtelte Patterns sind möglich (s. Zeile 4):

JEP-431: Sequenced Collections

Unter den verschiedenen Collections im JDK gibt es etliche, die für ihre beinhalteten Elemente eine definierte Auftrittsreihenfolge aufweisen. Bisher gab es allerdings kein einheitliches Interface, das diese Eigenschaft zum Ausdruck bringt.

Mit Sequenced Collections ändert sich dies nun. Damit wird der Zugriff auf das erste oder letzte Element der Collection, oder auch das Umkehren der Collection, möglich:

Die Interfaces List und Deque leiten nun von SequencedCollection ab, welche wiederum das Interface „Collection“ erweitert um die Methoden addFirst(…), addLast(…), getFirst(), getLast(), removeFirst(), removeLast() und reversed(). Daneben stellt das JDK auch die Interfaces SequencedSet und SequencedMap bereit.

Die neue Typhierarchie der Collections inklusive der neuen Sequenced Interfaces ist hier zu sehen: https://cr.openjdk.org/~smarks/collections/SequencedCollectionDiagram20220216.png.

JEP-439: Generational ZGC

Der seit Java 15 verfügbare ZGC Garbage Collector verfügt bisher über nur einen einzigen Speicherbereich, in dem alle Objekte abgelegt werden. Ab Java 21 kann ZGC die Objekte in seperaten, sogenannten Generational Spaces speichern. Alle neuen Objekte werden zunächst im „Young Space“ abgelegt. Objekte die ein paar GC-Zyklen überdauern, werden in den sogenanngen „Old Space“ verschoben. Hierdurch ergibt sich eine weitere Verbesserung der ohnehin schon sehr guten Performance des ZGC.

Um den Generational ZGC zu aktivieren, muss neben dem Kommandozeilenparameter -XX:+UseZGC die Option -XX:+ZGenerational angegeben werden:

$ java -XX:+UseZGC -XX:+ZGenerational …

So wird sichergestellt, dass sich das Verhalten des GC bei Umstellung auf Java 21 nicht automatisch ändert, wenn man die Kommandozeilenparameter nicht anpasst.

In einem zukünftigen Release soll Generational ZGC zum Standard werden.

Preview Features

Auch einige Preview-Features sind in Java 21 wieder mit dabei. Ein paar davon waren bereits in vorangehenden Releases als Preview enthalten und wurden weiterentwickelt, wie z.B. die Foreign Function & Memory API oder die Vector API (eine kurze Zusammenfassung hatte ich hier schonmal geschrieben). Die Scoped Values wurden vom Incubator- zum Preview-Feature „befördert“.

Es sind aber auch ein paar spannende neue Previews mit dabei. Für die Nutzung muss beim Kompilieren wie auch der Ausführung der Kommandozeilenparameter –-enable-preview gesetzt sein.

JEP-443: Unnamed Patterns and Variables (Preview)

Nicht genutzte Komponenten in Record Patterns oder ungenutze Variablen müssen nun nicht mehr benannt werden. Stattdessen können sie den Unterstrich „_“ als Bezeichner erhalten. Dies macht den Code besser verständlich, da der Entwickler so explizit ausdrücken kann, dass ein bestimmtes Konstrukt, das im Code angegeben werden muss, nicht benötigt wird.

Möchte man in einem Record Pattern für Point nur die x-Koordinate verwenden, nicht aber die y-Koordinate, kann man dies wie folgt schreiben:

Es ist auch möglich, den Datentyp wegzulassen:

Zudem können außerhalb von Patterns auch ungenutzte Variablen entsprechend benannt werden:

Auch für Exceptions in catch-Anweisungen kann _ verwendet werden:

Dasselbe gilt für ungenutzte Parameters von Lambdas. In Zeile 6 wird beispielsweise ein CommandLineRunner definiert, der die Kommandozeilenparameter nicht benötigt:

JEP-430: String Templates (Preview)

Mit diesem lang erwarteten Feature können nun Ausdrücke in String-Literale eingebettet werden:

Ausdrücke werden mit \{ eingeleitet und mit } geschlossen. Bei STR handelt es sich um einen StringTemplate-Processor, der die Ausdrücke auswertet und das Ergebnis an die jeweilige Stelle im String-Template einfügt.

Auch Textblöcke werden unterstützt, was z.B. sehr praktisch ist um JSON oder sonstige mehrzeilige Strings zu erzeugen:

Sehr praktisch ist, dass doppelte Anführungszeichen in String Templates nicht escaped werden müssen. Das Ergebnis sieht wie folgt aus:

Neben STR gibt es auch FMT, einen FormatProcessor, der das Formatieren anhand der Formatter-Spezifikation erlaubt:

Doch lediglich Werte in Strings zu parsen ging den Designern des Features nicht weit genug. Bei Erzeugung von SQL-Statements besteht beispielsweise die Gefahr der SQL-Injection:

Mit dem Wert „Smith‘ OR p.last_name ‚Smith“ ließe sich ein Statement erzeugen, das alle Einträge von Person zurückliefert. Daher soll der TemplateProcessor-Mechanismus in Java es ermöglichen, verschiedene Prozessoren für unterschiedliche Einsatzgebiete bereitzustellen. Deswegen ist es möglich, eigene Prozessoren zu schreiben, die valide bzw. sichere Ergebnisse produzieren. Im obigen Fall könnte z.B. ein SQL-Prozessor die Anführungszeichen in den Ausdruckswerten escapen.

Das Ergebnis muss nicht unbedingt vom Typ String sein; somit wäre auch ein Prozessor denkbar, der als Ergebnis ein JSON-Objekt hat.

Hier ein Beispiel für einen selbstgeschriebenen Template-Prozessor, der alle Werte spiegelt:

JEP-445: Unnamed Classes and Instance Main Methods (Preview)

Damit soll Java-Anfängern der Einstieg erleichtert werden. Um ein erstes Java-Programm zu schreiben soll es nicht nötig sein, sich mit Konzepten wie „class“, „static“ u.ä. beschäftigen zu müssen. Ein minimales Hello-World-Programm kann daher künftig so aussehen:

Dies ist tatsächlich der komplette Inhalt der Datei Hello.java und kann so kompiliert und ausgeführt werden (derzeit noch mit dem Kommandozeilenparameter –enable-preview). Der Java-Compiler ergänzt die Klasse automatisch.

Jagt man die kompilierte Datei Hello.class durch einen Decompiler, erhält man dieses Ergebnis:

Fazit

Java 21 ist vollgepackt mit neuen Features und Previews, auf die ich mich jetzt schon freue – auch wenn es wohl noch eine Weile dauern wird, bis ich sie im Kundenprojekt werde einsetzen können.

Der Beitrag Java 21 im Überblick erschien zuerst auf Business -Software- und IT-Blog - Wir gestalten digitale Wertschöpfung.



This post first appeared on DoubleSlash IT Business Und Software, please read the originial post: here

Share the post

Java 21 im Ãœberblick

×

Subscribe to Doubleslash It Business Und Software

Get updates delivered right to your inbox!

Thank you for your subscription

×