Выпуск Java SE 23 и OpenJDK 23

После шести месяцев разработки компания Oracle опубликовала платформу Java SE 23 (Java Platform, Standard Edition 23), в качестве эталонной реализации которой используется открытый проект OpenJDK. За исключением удаления некоторых устаревших возможностей в Java SE 23 сохранена обратная совместимость с прошлыми выпусками платформы Java — большинство ранее написанных Java-проектов без изменений будут работоспособны при запуске под управлением новой версии. Готовые для установки сборки Java SE 22 (JDK, JRE и Server JRE) подготовлены для Linux (x86_64, AArch64), Windows (x86_64) и macOS (x86_64, AArch64). Разработанная в рамках проекта OpenJDK эталонная реализация Java 23 полностью открыта под лицензией GPLv2 с исключениями GNU ClassPath, разрешающими динамическое связывание с коммерческими продуктами.

Java SE 23 отнесён к категории выпусков с обычным сроком поддержки, обновления для которого будут выпускаться до следующего релиза. В качестве ветки с длительным сроком поддержки (LTS) следует использовать Java SE 21 или Java SE 17, обновления для которых будут выпускаться до 2031 и 2029 годов соответственно (общедоступные — до 2028 и 2026 годов). Расширенная поддержка LTS-ветки Java SE 8 продлится до 2030 года, а Java SE 11 — до 2032 года.

Среди предложенных в Java SE 23 новшеств:

  • Включён по умолчанию генеративный режим работы сборщика мусора ZGC (Generational Z Garbage Collector), использующий раздельную обработку «старых» и «молодых» объектов, что повышает эффективность очистки недавно созданных объектов с небольшим временем жизни. Применение Generational ZGC уменьшает риски приостановок во время выделения ресурсов, снижает нагрузку на CPU и потребление памяти при сборке мусора. Тестирование Generational ZGC с Apache Cassandra 4 показало увеличение пропускной способности в 4 раза при фиксированном размере кучи (heap) и уменьшение размера кучи на четверть при неизменной пропускной способности.
  • В JavaDoc добавлена поддержка использования разметки в формате Markdown для документирования кода в комментариях, вместо смеси из HTML и @-тегов JavaDoc.
  • Механизмы сопоставления с образцом расширены предварительной поддержкой использования примитивных типов (int, byte, char и другие базовые типы, не являющиеся объектами) во всех видах шаблонов, в операторе «instanceof» и в блоках «switch»
    
       switch (x.getStatus()) {
           case 0 -› "okay";
           case 1 -› "warning";
           case 2 -› "error";
           case int i -› "unknown status: " + i;
       }
       if (i instanceof byte b) {
        ... b ...
       }
    
  • Добавлена предварительная поддержка использования одного выражения «import module M» для импорта сразу всех пакетов, экспортируемых указанным модулем. Изменение существенно упрощает повторное использование модульных библиотек, позволяя подключать библиотеки и классы без определения из места в иерархии пакетов. Например, указание «import module java.base» приведёт к импорту всех 54 пакетов, входящих в модуль java.base, которые ранее потребовалось бы упоминать по-отдельности («import java.io.*», «import java.util.*» и т.п.).

    Предложена вторая предварительная реализация API Class-File для разбора, генерации и преобразования файлов с классами Java.

    
       ClassFile cf = ClassFile.of();
       ClassModel classModel = cf.parse(bytes);
       byte[] newBytes = cf.build(classModel.thisClass().asSymbol(),
            classBuilder -> {
                for (ClassElement ce : classModel) {
                    if (!(ce instanceof MethodModel mm
                            && mm.methodName().stringValue().startsWith("debug"))) {
                        classBuilder.with(ce);
                    }
                }
            });
    
  • Предложена восьмая предварительная реализация API Vector, предоставляющего функции для векторных вычислений, которые выполняются с использованием векторных инструкций процессоров x86_64 и AArch64 и позволяют одновременно применить операции сразу к нескольким значениям (SIMD). В отличие от предоставляемых в JIT-компиляторе HotSpot возможностей по автовекторизации скалярных операций, новый API даёт возможность явно управлять векторизацией для параллельной обработки данных.
  • В класс java.io.Console добавлены методы format, printf, readPassword и readLine для форматирования, вывода и чтения текста с учётом выбранной локали.
    
       System.console().printf(Locale.FRANCE, "%1$tY-%1$tB-%1$te %1$tA", new Date())
       2024-mai-16 jeudi
    
  • Добавлена вторая предварительная реализация расширенного API Stream, поддерживающего определение собственных промежуточных операций, которые могут оказаться полезны в случаях, когда существующих встроенных промежуточных операций недостаточно для желаемого преобразования данных. Собственные обработчики подключаются при помощи новой промежуточной операции Stream::gather(Gatherer), которая обрабатывает элементы потока, применяя к ним заданный пользователем обработчик.
    
       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]]
    
  • Добавлена третья предварительная реализация неявно объявленных классов и безымянных экземпляров метода «main», в которых можно обойтись без объявлений public/static, передачи массива аргументов и прочих сущностей, связанных с объявлением класса.
    
       // было
       public class HelloWorld {
         public static void main(String[] args) {
           System.out.println("Hello world!");
         }
       }
    
       // теперь можно
       void main() {
           System.out.println("Hello, World!");
       }
    
  • Добавлен второй предварительный вариант возможности, разрешающей указание в конструкторах выражений перед вызовом super(…), используемого для явного вызова конструктора родительского класса из конструктора наследуемого класса, если эти выражения не ссылаются на создаваемый конструктором экземпляр.
    
       class Outer {
           void hello() {
               System.out.println("Hello");
           }
           class Inner {
               Inner() {
                   hello();
                   super();
               }
           }
       }
    
  • Добавлена третья предварительная реализация ограниченных значений (Scoped Values), позволяющих совместно использовать неизменяемые данные в потоках и эффективно обмениваться данными между дочерними потоками (значения наследуются). Scoped Values развиваются для замены механизма переменных локальных к потоку (thread-local variables) и более эффективны при использовании очень большого числа виртуальных потоков (тысячи и миллионы потоков). Главное отличие Scoped Values от переменных локальных к потоку в том, что первые записываются один раз, в дальнейшем не могут быть изменены и остаются доступны только на время выполнения потока.
  • Предложен для тестирования третий предварительный вариант API для cтруктурированного параллелизма (Structured Concurrency), упрощающего разработку многопоточных приложений за счёт обработки нескольких задач, выполняемых в разных потоках, как единого блока.
  • Объявлены устаревшими и намечены к удалению методы доступа к внешней памяти (вне JVM), предоставляемые классом sun.misc.Unsafe. Для обращения к памяти вне кучи (off-heap) и взаимодействия с внешними кодом рекомендуется использовать API VarHandle и API FFM (Foreign Function & Memory).

Источник: http://www.opennet.ru/opennews/art.shtml?num=61884