Java SE 21 отнесён к категории выпусков с расширенным сроком поддержки, обновления для которого будут выпускаться до 2031 года (общедоступные обновления будут выходить до сентября 2028 года). В качестве ветки с длительным сроком поддержки (LTS) также продолжает сопровождаться Java SE 17, обновления для которой будут выпускаться до 2029 года (общедоступные — до 2026 года).
Общедоступная поддержка LTS-ветки Java SE 11 прекращается в сентябре этого года, но расширенная поддержка будет производиться до 2032 года. Расширенная поддержка LTS-ветки ava SE 8 продлится до 2030 года.
Напомним, что начиная с выпуска Java 10 проект перешёл на новый процесс разработки, подразумевающий более короткий цикл формирования новых релизов. Новая функциональность теперь развивается в одной постоянно обновляемой master-ветке, в которую включаются уже готовые изменения и от которой раз в шесть месяцев ответвляются ветки для стабилизации новых выпусков.
Из новшеств Java 21 можно отметить ([1], [2], [3], [4], [5]):
- Добавлена предварительная поддержка строковых шаблонов (String Template), реализованных в дополнение к строковым литералам и блокам текста. Строковые шаблоны позволяют совмещать текст с вычисляемыми выражениями и переменными без использования оператора «+». Подстановка выражений осуществляется при помощи подстановок {..}, при этом для проверки корректности подставляемых значений могут подключаться специальные обработчики. Например, обработчик SQL обеспечивает проверку значений, подставляемых в SQL-код, и возвращает на выходе объект java.sql.Statement, а обработчик JSON отслеживает корректность подстановок JSON и возвращает JsonNode.
String query = "SELECT * FROM Person p WHERE p." + property + " = '" + value + "'"; // было Statement query = SQL."""SELECT * FROM Person p WHERE p.{property} = '{value}'"""; // стало
- Добавлена поддержка упорядоченных коллекций (SequencedCollection), предоставляющих методы addFirst, addLast, getFirst, getLast, removeFirst и removeLast для прямого доступа к первым и последним элементам коллекции с постоянным следованием элементов. Упорядоченные коллекции применимы к спискам, sets-наборам (например, TreeSet) и некоторым другим структурам данных.
var letters = List.of("c", "b", "a"); "c".equals(letters.getFirst()); "a".equals(letters.getLast());
- Реализован генеративный вариант сборщика мусора ZGC (Generational Z Garbage Collector), вводящий раздельную обработку «старых» и «молодых» объектов, что повышает эффективной очистки недавно созданных объектов с небольшим временем жизни. Отмечается, что применение Generational ZGC уменбшает риски приостановок во время выделения ресурсов, снижает нагрузку на CPU и потребление памяти при сборке мусора. Применение Generational ZGC с Apache Cassandra 4 в проведённых тестах привело к увеличению пропускной способности в 4 раза при фиксированном размере кучи (heap) и уменьшение размера кучи на четверть при неизменной пропускной способности. Для включения нового режима предложена опция «-XX:+UseZGC -XX:+ZGenerational».
- Стабилизирована реализация шаблонов записей (record pattern), расширяющая появившуюся в Java 16 возможность сопоставления с образцом средствами для разбора значений классов типа record. Например:
record Point(int x, int y) {} static void printSum(Object obj) { if (obj instanceof Point p) { int x = p.x(); int y = p.y(); System.out.println(x+y); } }
- Стабилизирована поддержка сопоставления по шаблону в выражениях «switch», позволяющая в метках «case» использовать не точные значения, а гибкие шаблоны, охватывающие сразу серию значений, для которых ранее приходилось использовать громоздкие цепочки выражений «if…else».
static String formatterPatternSwitch(Object obj) { return switch (obj) { case Integer i -> String.format("int %d", i); case Long l -> String.format("long %d", l); case Double d -> String.format("double %f", d); case String s -> String.format("String %s", s); default -> o.toString(); }; }
- Стабилизирована реализация виртуальных потоков, представляющих собой легковесные потоки, значительно упрощающие написание и сопровождение высокопроизводительных многопоточных приложений.
- Предложена третья предварительная реализация API FFM (Foreign Function & Memory), позволяющего организовать взаимодействие Java-программ с внешними кодом и данными через вызов функций из внешних библиотек и доступ к памяти вне JVM.
- Добавлена предварительная поддержка безымянных переменных и сопоставлений с шаблоном — вместо неиспользуемых, но необходимых при вызове переменных и шаблонов, теперь можно указывать символ «_».
// было String pageName = switch (page) { case GitHubIssuePage(var url, var content, var links, int issueNumber) -› "ISSUE #" + issueNumber; ... }; // теперь можно String pageName = switch (page) { case GitHubIssuePage(_, _, _, int issueNumber) -› "ISSUE #" + issueNumber; };
- Добавлена предварительная поддержка безымянных классов и безымянных экземпляров метода «main», в которых можно обойтись без объявлений public/static, передачи массива аргументов и прочих сущностей, связанных с объявлением класса.
// было public class HelloWorld { public static void main(String[] args) { System.out.println("Hello world!"); } } // теперь можно void main() { System.out.println("Hello, World!"); }
- Добавлена предварительная поддержка ограниченных значений (Scoped Values), позволяющих совместно использовать неизменяемые данные в потоках и эффективно обмениваться данными между дочерними потоками (значения наследуются). Scoped Values развиваются для замены механизма переменных локальных к потоку (thread-local variables) и более эффективны при использовании очень большого числа виртуальных потоков (тысячи и миллионы потоков). Главное отличие Scoped Values от переменных локальных к потоку в том, что первые записываются один раз, в дальнейшем не могут быть изменены и остаются доступны только на время выполнения потока.
class Server { final static ScopedValue‹user› CURRENT_USER = new ScopedValue‹›(); void serve(Request request, Response response) { var level = (request. isAuthorized()? ADMIN : GUEST); var user = new User(level); ScopedValue.where(CURRENT_USER, user) .run(() -> Application.handle(request, response)); } } class DatabaseManager { DBConnection open() { var user = Server.CURRENT_USER.get(); if (!user.canOpen()) throw new InvalidUserException(); return new DBConnection(...); } }
- Добавлена шестая предварительная реализация API Vector, предоставляющего функции для векторных вычислений, которые выполняются с использованием векторных инструкций процессоров x86_64 и AArch64 и позволяют одновременно применить операции сразу к нескольким значениям (SIMD). В отличие от предоставляемых в JIT-компиляторе HotSpot возможностей по автовекторизации скалярных операций, новый API даёт возможность явно управлять векторизацией для параллельной обработки данных.
- Добавлен экспериментальный API для cтруктурированного параллелизма (Structured Concurrency), упрощающий разработку многопоточных приложений за счёт обработки нескольких задач, выполняемых в разных потоках, как единого блока.
- Добавлены новые методы: Math.clamp(), StrictMath.clamp(), String indexOf(int,int,int), indexOf(String,int,int), String splitWithDelimiters().
- Добавлены методы для определения свойств emoji: isEmoji(int codePoint),
isEmojiPresentation(int codePoint),
isEmojiModifier(int codePoint),
isEmojiModifierBase(int codePoint),
isEmojiComponent(int codePoint) и isExtendedPictographic(int codePoint).var codePoint = Character.codePointAt("?", 0); var isEmoji = Character.isEmoji(codePoint); System.out.println("? is an emoji: " + isEmoji);
- Добавлен API для использования механизмов инкапсуляции ключей шифрования (KEM, Key Encapsulation Mechanism),
предназначенных для защиты ключей симметричного шифрования при помощи алгоритмов на основе открытых ключей. - Добавлена поддержка алгоритма цифровых подписей HSS/LMS.
- Началась подготовка к запрету динамической загрузки агентов. При попытке динамической загрузки Java-агентов в работающую виртуальную машину JVM теперь будет выводиться предупреждение.
- Прекращена поддержка 32-разрядной платформы Windows.
Дополнительно можно отметить публикацию обновления платформы для создания приложений с графическим интерфейсом JavaFX 21.
Источник: http://www.opennet.ru/opennews/art.shtml?num=59787