Что нового в Java 23
В сентябре ожидается выход новой Java 23, а список JDK Enhancement Proposal (JEP) сформирован и доступен уже сейчас.
Оцените изменения в JDK 23, чтобы заранее продумать миграцию на версию с долгосрочной поддержкой (LTS), потому что JDK 23 не является LTS-версией.
В этой статье вы узнаете какие JEP вошли в новую Java и чего коснутся эти изменения.
Содержание:
- Новое
- Улучшения
- JEP 466: Class-File API (вторая предварительная версия)
- JEP 469: Vector API (восьмой инкубатор)
- JEP 473: Stream Gatherers (вторая предварительная версия)
- JEP 474: Сборщик мусора ZGC по умолчанию — generational
- JEP 477: Неявные классы и
main
-методы экземпляра класса (третья предварительная версия) - JEP 480: Структурированный параллелизм (третья предварительная версия)
- JEP 481: Scoped Values (третья предварительная версия)
- JEP 482: Гибкий конструктор (вторая предварительная версия)
- Устаревшее (deprecated)
- Переходите на Axiom JDK Pro с улучшенными функциями безопасности и поддержкой отечественных инженеров
Новое
JEP 455: Примитивные типы в шаблонах pattern matching, instanceof
и switch
(предварительная версия)
Эта функция улучшит pattern matching, позволив использовать примитивные типы во всех контекстах шаблонов, а также расширит функции instanceof
и switch
для работы со всеми примитивными типами.
Цели этого JEP — устранить риск потери данных из-за небезопасного приведения типов и позволить исследовать данные примитивных или ссылочных типов единым образом. Раньше instanceof
работал только со ссылочными типами, и не было способа проверить примитивные значения на безопасность приведения. Из-за этого примитивное значение могло быть тихо преобразовано без выброса исключения. Теперь оператор instanceof
проверяет примитивные типы. Если значение может быть безопасно приведено, instanceof
вернёт true
, иначе — false
.
JEP 467: Поддержка Markdown в JavaDoc-комментариях
При написании JavaDoc-комментариев будет использоваться Markdown, а не только сочетание HTML и тегов JavaDoc. Это облегчит чтение и написание комментариев в исходном виде для API. Markdown не заменит HTML и теги JavaDoc, а станет дополнительным способом написания комментариев для документирования.
JEP 476: Импортирование модулей (предварительная версия)
Java 23 позволит импортировать сам модуль вместо явного импортирования его отдельных пакетов. Это упростит переиспользование модульных библиотек путём одновременного импортирования модулей.
Также это сократит число строк в коде для импорта нужных пакетов модуля. Начинающие разработчики смогут импортировать требуемые библиотеки и системные Java-классы без необходимости изучать их положение в иерархии пакетов.
Так, вместо:
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
Или:
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
Достаточно написать:
import module java.base
Улучшения
JEP 466: Class-File API (вторая предварительная версия)
В Java 22 в предварительной версии появилось стандартный API для парсинга, генерации и трансформации class-файлов. Этот API будет развиваться вместе с форматом класс-файлов и позволит компонентам и фреймворкам Java-платформы использовать его вместо сторонних библиотек.
Во второй предварительной версии внедрены следующие улучшения на основе обратной связи:
- Упрощён класс
CodeBuilder
. - Экземпляры
AttributeMapper
вAttributes
теперь доступны через статические методы, а не через статические поля. Это позволяет реализовать отложенную (“ленивую”) инициализацию и снизить затраты на запуск Java. - Переделали
Signature.TypeArg
в алгебраический тип данных. - Добавлены
ClassReader.readEntryOrNull
иConstantPool.entryByIndex
, которые выбрасываютConstantPoolException
вместоClassCastException
, если запись по индексу не требуемого типа. Процессоры Class-File смогут указывать, что несоответствие типа записи набора констант — это проблема формата Class-File, а не процессора. - Класс
ClassSignature
точнее моделирует общие сигнатуры суперклассов и суперинтерфейсов. - Исправлена опечатка в несоответствии имён в
TypeKind
. - Удалены подробные методы реализации в
ClassReader
.
JEP 469: Vector API (восьмой инкубатор)
Vector API появилось в JDK 16 и пока остаётся в инкубационном периоде. В восьмом инкубаторе всё без изменений.
Vector API использует SIMD-инструкции (Single Instruction, Multiple Data), распараллеливая векторные вычисления.
Vector API остаётся в инкубаторе, потому что зависит от некоторых функциональностей проекта Valhalla, который находится в разработке. Как только этот проект станет доступен в предварительной версии, векторное API так же перейдёт из инкубатора в предварительную версию.
JEP 473: Stream Gatherers (вторая предварительная версия)
Stream Gatherers появились в JDK 22 для усовершенствования Stream API поддержкой пользовательских intermediate-операторов. Во второй предварительной версии нет изменений по сравнению с JDK 22, цель этой версии — собрать дополнительную обратную связь и улучшить опыт использования.
Stream Gatherers позволит стримам преобразовывать данные более лёгкими способами по сравнению с существующими встроенными intermediate-операторами. Цели создания Stream Gatherers — сделать стримы более гибкими и позволить пользовательским intermediate-операторам управлять бесконечными потоками. До Stream Gatherers для создания необходимой логики в уже существующих intermediate-операторах приходилось создавать отдельные классы или методы. Теперь вместо этого введён Stream::gather(Gatherer)
, который позволяет обрабатывать потоки в определённом пользователем порядке.
JEP 474: Сборщик мусора ZGC по умолчанию — generational
Сборщик мусора Z Garbage Collector (ZGC) появился ещё в Java 21. В Java 23 non-generational признан устаревшим и будет удалён в следующей версии. Цели этого JEP — снизить затраты на поддержку двух сборщиков мусора ZGC: non-generational и generational и предупредить о дальнейшем фокусе разработки на generational.
Раньше ZGC хранил молодые и старые объекты вместе и собирал все объекты сразу. С созданием generational, ZGC хранит молодые и старые объекты в разных областях и чаще собирает молодые объекты, что уменьшает потребление ресурсов CPU и кучи при сборке мусора.
JEP 477: Неявные классы и main
-методы экземпляра класса (третья предварительная версия)
Эта функциональность была включена в JDK 21. С её помощью начинающие Java-разработчики могут писать простые программы без сложных конструкций корпоративной разработки, а затем усложнять свои программы по мере углубления знаний. Опытные разработчики смогут писать лаконичные приложения без компонентов, используемых для программирования крупных систем.
Так выглядит базовая программа Hello World!
, которая изучается новичками в Java:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
Для простой по сути программы на Java здесь много кода, непонятных новичку понятий и конструкций: class
с модификатором доступа public
, параметр String[] args
, модификатор static
и System.out.println
.
Неявные классы имеют только конструктор zero-parameter по умолчанию, находящийся в пакете unnamed
, на который нельзя ссылаться по имени. Каждый неявный класс должен содержать метод main
и представлять собой самостоятельную программу.
Тогда Hello World!
упрощается до трёх строк:
void main() {
System.out.println("Hello, World!");
}
В третьей предварительной версии добавилось следующее:
-
Неявные классы автоматически импортируют три статических метода для простого текстового ввода и вывода с консоли. Эти методы объявлены в новом классе верхнего уровня
java.io.IO
:public static void println(Object obj)
,public static void print(Object obj)
,public static String readln(String prompt)
.
Теперь можно обойтись без System.in
и System.out
и связанных с ними понятий, усложняющих понимание в начале изучения Java. Так, простая интерактивная программа упрощается до:
void main() {
String name = readln("Введите своё имя: ");
print("Приятно познакомиться, ");
println(name);
}
- Неявные классы автоматически по требованию импортируют все публичные классы верхнего уровня и интерфейсы пакетов, экспортируемых модулем
java.base
. Станет возможным использование API из широко используемых пакетов в теле неявного класса, как если бы эти пакеты были импортированы.
JEP 480: Структурированный параллелизм (третья предварительная версия)
Чтобы упростить многопоточное программирование, в JDK 19 было представлено API структурированного параллелизма. Это третья предварительная версия этого API, которая будет включена в JDK 23 без изменений для получения обратной связи от разработчиков.
Структурированный параллелизм рассматривает группы связанных задач, выполняемых в разных потоках, как единое целое. Задача расщепляется на несколько подзадач, которые выполняются в отдельных потоках. Затем эти подзадачи воссоединяются в блоке кода главной задачи. Таким образом, задача координирует выполнение подзадач и отслеживать ошибки их выполнения. Это устраняет риски, связанные с отменой и внезапным завершением работы, и повышает надёжность многопоточных приложений.
- Взаимосвязь между задачами и подзадачами будет чётко прослеживаться в структуре кода, что повышает наблюдаемость.
- Если происходит сбой в подзадаче или поток, выполняющий задачи, прерывается до
join()
, то другие подзадачи отменяются. Это повышает надёжность кода.
JEP 481: Scoped Values (третья предварительная версия)
Scoped values впервые появились в JDK 20 в режиме инкубатора. В третьей предварительной версии внесено одно изменение: метод ScopedValue.getWhere
будет удалён. Этот метод заменит новый функциональный интерфейс, позволяющий JVM понять, будет ли выброшено исключение.
Scoped values позволяют расшаривать неизменяемые данные в рамках одного потока и между потоками. Scoped values следует использовать вместо локальных переменных потока (thread locals), поскольку они уменьшают сложность кода и повышают надёжность многопоточных приложений.
JEP 482: Гибкий конструктор (вторая предварительная версия)
Эта функциональность появилась в JDK 22 и называлась JEP 447: Выражения перед super(…). Чтобы уменьшить объём и сложность кода, можно добавлять инструкции в конструкторе перед явным вызовом конструктора super()
или this()
. Это не нарушает естественный порядок инициализации сверху-вниз (top-down).
Во второй предварительной версии изменилось следующее: конструктор сможет инициализировать поля в том же классе перед явным вызовом конструктора. Так конструктор суперкласса (superclass) не выполнит код, который увидит значение поля по умолчанию подкласса (например, 0
, false
или null
). Это может произойти, когда из-за переопределения конструктор суперкласса вызывает метод в подклассе, используя некоторое поле.
Устаревшее (deprecated)
JEP 471: Подготовка к удалению методов доступа к памяти в sun.misc.Unsafe
Цель создания класса sun.misc.Unsafe
— выполнение низкоуровневых операций в JDK, поскольку этот класс содержит методы для доступа к памяти on-heap и off-heap. Эти методы могут помочь увеличить производительность в некоторых специфических сценариях, но только в том случае, если по пути выполняются исчерпывающие проверки на безопасность. Иначе использование этих методов может привести к неожиданному поведению приложения, сбоям JVM или снижению производительности. Многие библиотеки используют sun.misc.Unsafe
, но не все выполняют требуемые проверки безопасности.
Для решения этой проблемы введены два запасных API: Variable Handles для доступа к памяти on-heap и Foreign Function & Memory API для работы с памятью off-heap.
С помощью этих API стало возможным вывести sun.misc.Unsafe
из использования с помощью JEP 471 и удалить этот класс в будущих выпусках.
Переходите на Axiom JDK Pro с улучшенными функциями безопасности и поддержкой отечественных инженеров
Axiom JDK поддерживает все LTS-релизы Java (8, 11, 17, 21), а также текущий релиз. Мигрируйте на любую версию Axiom JDK Pro и получайте ежеквартальные обновления безопасности, экстренные патчи и доступ к возможностям для российских разработчиков:
- доверенному репозиторию Java-библиотек,
- Axiom JDK Certified, сертифицированному ФСТЭК по 4 ОУД.
- Axiom JDK Express, который улучшает пропускную способность, время отклика и время запуска проектов на базе JDK 8 или 11 за счёт виртуальной машины JVM 17.
Свяжитесь с нами, наши инженеры расскажут о продуктах Axiom JDK, предоставят демо-версию и помогут с миграцией.
Вступайте в наш Telegram-канал, чтобы быть в курсе новостей мира Java.