Veröffentlichung der Java SE 22-Plattform und der offenen Referenzimplementierung OpenJDK 22

Nach sechs Monaten Entwicklungszeit hat Oracle die Plattform Java SE 22 (Java Platform, Standard Edition 22) veröffentlicht, die das Open-Source-Projekt OpenJDK als Referenzimplementierung verwendet. Mit Ausnahme der Entfernung einiger veralteter Funktionen behält Java SE 22 die Abwärtskompatibilität mit früheren Versionen der Java-Plattform bei – die meisten zuvor geschriebenen Java-Projekte funktionieren weiterhin ohne Änderungen, wenn sie unter der neuen Version ausgeführt werden. Installierbare Builds von Java SE 22 (JDK, JRE und Server JRE) sind für Linux (x86_64, AArch64), Windows (x86_64) und macOS (x86_64, AArch64) vorbereitet. Die vom OpenJDK-Projekt entwickelte Java 22-Referenzimplementierung ist vollständig Open Source unter der GPLv2-Lizenz mit GNU ClassPath-Ausnahmen, um eine dynamische Verknüpfung mit kommerziellen Produkten zu ermöglichen.

Java SE 22 wird als reguläres Support-Release eingestuft und wird bis zum nächsten Release weiterhin Updates erhalten. Der Long Term Support (LTS)-Zweig sollte Java SE 21 oder Java SE 17 sein, die bis 2031 bzw. 2029 Updates erhalten (allgemein verfügbar bis 2028 und 2026). Die öffentliche Unterstützung für den LTS-Zweig von Java SE 11 endete letzten September, die erweiterte Unterstützung wird jedoch bis 2032 fortgesetzt. Die erweiterte Unterstützung für den LTS-Zweig von Java SE 8 wird bis 2030 fortgesetzt.

Wir möchten Sie daran erinnern, dass das Projekt mit der Veröffentlichung von Java 10 auf einen neuen Entwicklungsprozess umgestellt hat, was einen kürzeren Zyklus für die Erstellung neuer Releases bedeutet. Neue Funktionen werden nun in einem ständig aktualisierten Hauptzweig entwickelt, der vorgefertigte Änderungen enthält und von dem alle sechs Monate Zweige abgezweigt werden, um neue Versionen zu stabilisieren.

Zu den neuen Funktionen in Java 22 gehören:

  • Der G1-Garbage Collector bietet Unterstützung für Region Pinning, wodurch Sie die Position von Java-Objekten im Speicher vorübergehend festlegen können, um zu verhindern, dass sie vom Garbage Collector verschoben werden, und um die sichere Weitergabe von Verweisen auf diese Objekte zwischen Java und nativem Code zu ermöglichen. Durch das Pinning können Sie die Latenz reduzieren und die Deaktivierung der Garbage Collection vermeiden, wenn Sie kritische Bereiche von JNI (Java Native Interface) mit nativem Code ausführen (während der Ausführung dieser Abschnitte sollte die JVM keine damit verbundenen kritischen Objekte verschieben, um Race Conditions zu vermeiden). Durch das Anheften werden kritische Objekte aus der Sicht des Garbage Collectors entfernt, wodurch nicht angeheftete Bereiche weiterhin bereinigt werden können.
  • Es wurde eine vorläufige Funktion hinzugefügt, die es ermöglicht, vor dem Aufruf von super(...) Ausdrücke in Konstruktoren anzugeben, mit denen explizit ein übergeordneter Klassenkonstruktor von einem geerbten Klassenkonstruktor aufgerufen werden kann, wenn diese Ausdrücke nicht auf eine vom Konstruktor erstellte Instanz verweisen. class Outer { void hello() { System.out.println("Hello"); } class Inner { Inner() { hello(); super(); } } }
  • Die FFM-API (Foreign Function & Memory) wurde stabilisiert und ermöglicht die Interaktion von Java-Programmen mit externem Code und Daten durch Aufrufen von Funktionen aus externen Bibliotheken und Zugriff auf Speicher außerhalb der JVM, ohne auf die Verwendung von JNI (Java Native Interface) zurückgreifen zu müssen.
  • Die Unterstützung für unbenannte Variablen und den Mustervergleich wurde aktiviert. Anstelle nicht verwendeter, aber notwendiger Variablen und Muster können Sie beim Aufruf jetzt das Zeichen „_“ angeben. // war String pageName = switch (page) { case GitHubIssuePage(var url, var content, var links, int issueNumber) -> „ISSUE #“ + issueNumber; ... }; // Jetzt können Sie String pageName = switch (page) { case GitHubIssuePage(_, _, _, int issueNumber) -> „ISSUE #“ + issueNumber; };
  • Für das Parsen, Generieren und Konvertieren von Java-Klassendateien wird eine vorläufige Implementierung der Class-File-API vorgeschlagen. ClassFile cf = ClassFile.of(); ClassModel classModel = cf.parse(bytes); byte[] newBytes = cf.build(classModel.thisClass().asSymbol(), classBuilder -> { for (ClassElement ce : classModel) { if (!(ce exampleof MethodModel mm && mm.methodName().stringValue(). startetWith("debug"))) { classBuilder.with(ce); } } });
  • Das Java-Dienstprogramm bietet die Möglichkeit, Java-Programme auszuführen, die in Form mehrerer Codedateien oder vorkompilierter Klassenbibliotheken bereitgestellt werden, ohne diese Dateien separat zu kompilieren und ohne das Build-System zu konfigurieren. Die neue Funktion erleichtert die Ausführung von Programmen, in denen der Code verschiedener Klassen in separate Dateien aufgeteilt ist. Prog.java: class Prog { public static void main(String[] args) { Helper.run(); } } Helper.java: class Helper { static void run() { System.out.println("Hello!"); } }

    Um beispielsweise ein Programm auszuführen, das aus zwei Dateien „Prog.java“ und „Helper.java“ besteht, reicht es nun aus, „java Prog.java“ auszuführen, wodurch die Prog-Klasse kompiliert wird, eine Referenz auf die Helper-Klasse definiert wird, Suchen und kompilieren Sie die Hilfsdatei. Java und rufen Sie die Hauptmethode auf.

  • Eine zweite vorläufige Implementierung von String-Vorlagen hinzugefügt, die zusätzlich zu String-Literalen und Textblöcken implementiert wird. Mithilfe von Zeichenfolgenvorlagen können Sie Text mit berechneten Ausdrücken und Variablen kombinieren, ohne den Operator „+“ zu verwenden. Die Ersetzung von Ausdrücken erfolgt über Substitutionen \{..}, wobei spezielle Handler angeschlossen werden können, um die Korrektheit der ersetzten Werte zu überprüfen. Beispielsweise prüft die SQL-Engine die Werte, die im SQL-Code ersetzt werden, und gibt als Ausgabe ein java.sql.Statement-Objekt zurück, während der JSON-Prozessor die Richtigkeit der JSON-Ersetzungen überwacht und einen JsonNode zurückgibt. String query = „SELECT * FROM Person p WHERE p.“ + Eigenschaft + " = '" + Wert + "'"; // was Statement query = SQL."""SELECT * FROM Person p WHERE p.\{property} = '\{value}'"""; // wurde
  • Es wurde eine siebte Vorschau der Vector API hinzugefügt, die Funktionen für Vektorberechnungen bereitstellt, die mithilfe von Vektoranweisungen auf x86_64- und AArch64-Prozessoren durchgeführt werden und die gleichzeitige Anwendung von Operationen auf mehrere Werte (SIMD) ermöglichen. Im Gegensatz zu den im HotSpot JIT-Compiler bereitgestellten Funktionen zur automatischen Vektorisierung skalarer Operationen ermöglicht die neue API die explizite Steuerung der Vektorisierung für die parallele Datenverarbeitung.
  • Es wurde eine vorläufige Implementierung der erweiterten Stream-API hinzugefügt, die die Definition eigener Zwischenoperationen unterstützt. Dies kann in Fällen nützlich sein, in denen vorhandene integrierte Zwischenoperationen für die gewünschte Datentransformation nicht ausreichen. Native Handler werden über die neue Zwischenoperation Stream::gather(Gatherer) verbunden, die Stream-Elemente verarbeitet, indem sie einen benutzerdefinierten Handler auf sie anwendet. jshell> Stream.of(1,2,3,4,5,6,7,8,9).gather(new WindowFixed(3)).toList() $1 ==> [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
  • Zum Testen wurde eine zweite Version der experimentellen API für strukturierte Parallelität vorgeschlagen, die die Entwicklung von Multithread-Anwendungen vereinfacht, indem mehrere in verschiedenen Threads ausgeführte Aufgaben als ein einziger Block verarbeitet werden.
  • Es wurde eine zweite vorläufige Implementierung implizit deklarierter Klassen und unbenannter Instanzen der „main“-Methode hinzugefügt, die auf öffentliche/statische Deklarationen, die Übergabe eines Arrays von Argumenten und andere mit einer Klassendeklaration verknüpfte Entitäten verzichten kann. // war eine öffentliche Klasse HelloWorld { public static void main(String[] args) { System.out.println("Hello world!"); } } // Jetzt können Sie void main() { System.out.println("Hello, World!"); }
  • Es wurde eine zweite Vorschauimplementierung von Scoped Values ​​hinzugefügt, die die gemeinsame Nutzung unveränderlicher Daten zwischen Threads und den effizienten Datenaustausch zwischen untergeordneten Threads ermöglicht (Werte werden vererbt). Bereichswerte werden entwickelt, um den Thread-lokalen Variablenmechanismus zu ersetzen und sind effizienter, wenn eine sehr große Anzahl virtueller Threads (Tausende oder Millionen Threads) verwendet wird. Der Hauptunterschied zwischen Scoped Values ​​und Thread-lokalen Variablen besteht darin, dass erstere einmal geschrieben werden, in Zukunft nicht mehr geändert werden können und nur für die Dauer der Thread-Ausführung verfügbar bleiben.
  • Der parallele Garbage Collector hat die Leistung beim Arbeiten mit großen Objektarrays verbessert. Durch die Optimierung konnte bei einigen Tests mit großen Objektarrays die Verzögerung vor Beginn der Suche nach einem Objekt um 20 % reduziert werden.

Darüber hinaus können Sie die Veröffentlichung eines Updates der Plattform zum Erstellen von Anwendungen mit einer grafischen Oberfläche JavaFX 22 zur Kenntnis nehmen.

Source: opennet.ru

Kommentar hinzufügen