После шести месяцев разработки компания Oracle выпустила платформу Java SE 17 (Java Platform, Standard Edition 17), в качестве эталонной реализации которой используется открытый проект OpenJDK. За исключением удаления некоторых устаревших возможностей в Java SE 17 сохранена обратная совместимость с прошлыми выпусками платформы Java – большинство ранее написанных Java-проектов без изменений будут работоспособны при запуске под управлением новой версии. Готовые для установки сборки Java SE 17 (JDK, JRE и Server JRE) подготовлены для Linux (x86_64, AArch64), Windows (x86_64) и macOS (x86_64, AArch64). Разработанная в рамках проекта OpenJDK эталонная реализация Java 17 полностью открыта под лицензией GPLv2 с исключениями GNU ClassPath, разрешающими динамическое связывание с коммерческими продуктами.
Java SE 17 отнесён к категории выпусков с длительным сроком поддержки (LTS), обновления для которого будут выпускаться до 2029 года. Выпуск обновлений для прошлого промежуточного выпуска Java 16 прекращён. Прошлая LTS-ветка Java 11 будет поддерживаться до 2026 года. Следующий LTS-релиз намечен на сентябрь 2024 года. Напомним, что начиная с выпуска Java 10 проект перешёл на новый процесс разработки, подразумевающий более короткий цикл формирования новых релизов. Новая функциональность теперь развивается в одной постоянно обновляемой master-ветке, в которую включаются уже готовые изменения и от которой раз в шесть месяцев ответвляются ветки для стабилизации новых выпусков.
Из новшеств Java 17 можно отметить:
- Предложена экспериментальная реализация сопоставления по шаблону в выражениях “switch”, позволяющая в метках “case” использовать не точные значения, а гибкие шаблоны, охватывающие сразу серию значений, для которых ранее приходилось использовать громоздкие цепочки выражений “if…else”. Кроме того внутри “switch” обеспечена возможности обработки значений NULL. Object o = 123L; String formatted = switch (o) { 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(); };
- Стабилизирована поддержка запечатанных (“sealed”) классов и интерфейсов, которые не могут использоваться другими классами и интерфейсами для наследования, расширения или переопределения реализации. Запечатанные классы также предоставляют более декларативный способ ограничения использования суперкласса, чем модификаторы доступа, основанный на явном перечислении подклассов, разрешённых для расширения. package com.example.geometry; public sealed class Shape permits com.example.polar.Circle, com.example.quad.Rectangle, com.example.quad.simple.Square {…}
- Предложена вторая предварительная реализация API Vector, предоставляющего функции для векторных вычислений, которые выполняются с использованием векторных инструкций процессоров x86_64 и AArch64 и позволяют одновременно применить операции сразу к нескольким значениям (SIMD). В отличие от предоставляемых в JIT-компиляторе HotSpot возможностей по автовекторизации скалярных операций, новый API даёт возможность явно управлять векторизацией для параллельной обработки данных.
- Добавлена предварительная реализация API Foreign Function & Memory, при помощи которого приложения могут взаимодействовать с кодом и данными, находящимися за пределами Java runtime. Новый API позволяет эффективно вызывать функции, выполняемые не в JVM, и обращаться к памяти, не управляемой JVM. Например, можно вызывать функции из внешних разделяемых библиотек и обращаться к данным процесса без использования JNI.
- Движок отрисовки для macOS, обеспечивающий работу API Java 2D, который, в свою очередь, задействован в API Swing, адаптирован для использования графического API Metal. По умолчанию на платформе macOS по-прежнему применяется OpenGL, а для включения поддержки Metal требуется установка параметра “-Dsun.java2d.metal=true” и наличие как минимум выпуска macOS 10.14.x.
- Добавлен порт для платформы macOS/AArch64 (компьютеры Apple на базе новых чипов Apple M1). Особенностью порта является поддержка механизма защиты памяти W^X (Write XOR Execute), при котором страницы памяти не могут быть одновременно доступны на запись и исполнение. (код может быть исполнен только после запрещения записи, а запись в страницу памяти возможна только после запрета исполнения).
- Возвращено использование только строгой (strictfp) семантики для выражений с плавающей запятой. Прекращена поддержка доступной начиная с выпуска Java 1.2 семантики “default”, включающей упрощения для работы на системах с очень старыми математическими сопроцессорами x87 (после появления инструкций SSE2 необходимость в дополнительной семантике пропала).
- Реализованы новые типы интерфейсов к генераторам псевдослучайных чисел, а также реализованы дополнительные алгоритмы для более качественной генерации случайных чисел. Приложениям предоставлена возможность выбора алгоритма генерации псевдослучайных чисел. Улучшена поддержка генерации потоков случайных объектов.
- Реализована обязательная строгая инкапсуляция всех внутренних элементов JDK, за исключением критических API, таких как sun.misc.Unsafe. Строгая инкапсуляция блокирует попытки обращения из кода к внутренним классам, методам и полям. Ранее режим строгой инкапсуляции можно было отключить при помощи опции “–illegal-access=permit”, но теперь она объявлена устаревшей. Для приложений, которым необходим доступ к внутренним классам, методам и полям следует явно определить их при помощи опции “–add-opens” или атрибута Add-Opens в файле с манифестом.
- Приложениям предоставлена возможность определять фильтры для десериализации данных, которые могут зависеть от контекста и выбираться динамически в привязке к определённым операциям десериализации. Задаваемые фильтры применимы ко всей виртуальной машине (JVM-wide), т.е. охватывают не только само приложение, но и используемые в приложении сторонние библиотеки.
- В Swing добавлен метод javax.swing.filechooser.FileSystemView.getSystemIcon для загрузки пиктограмм большого размера, позволяющий улучшить формирование интерфейса на экранах с большой плотностью пикселей (HighDPI).
- В API java.net.DatagramSocket реализована поддержка подключения к группам Multicast без необходимости использования отдельного API java.net.MulticastSocket.
- Усовершенствована утилита IGV (Ideal Graph Visualizer), обеспечивающая интерактивную визуализацию промежуточного представления кода в JIT-компиляторе HotSpot VM C2.
- В JavaDoc по аналогии с компилятором javac при выводе ошибки теперь указывается номер проблемной строки в исходном файле и место ошибки.
- Добавлено свойство native.encoding, отражающее имя системной кодировки символов (UTF-8, koi8-r, сp1251 и т.п.).
- Добавлен интерфейс java.time.InstantSource, позволяющий манипулировать временем без привязки к часовому поясу.
- Добавлен API java.util.HexFormat для преобразования в шестнадцатеричное представление и наоборот.
- В компилятор добавлен режим blackhole, отключающий операции исключения неиспользуемого кода (dead-code elimination), что может быть использована при проведении тестов производительности.
- В Runtime добавлена опция “-Xlog:async” для записи логов в асинхронном режиме.
- При установке защищённых соединений по умолчанию задействован TLS 1.3 (ранее использовался TLS 1.2).
- Переведён в категорию намеченных для удаления ранее объявленный устаревшим API Applet (java.applet.Applet*, javax.swing.JApplet), применявшийся для запуска Java-приложений в браузере (потерял актуальность после прекращения поддержка Java-плагина для браузеров).
- Переведён в категорию намеченных для удаления Security Manager, который давно потерял актуальность и оказался невостребованным после прекращения поддержки браузерного плагина.
- Удалён механизм RMI Activation, который устарел, переведён в разряд опции ещё в Java 8 и почти не применяется в современной практике.
- Из SDK удалён экспериментальный компилятор, поддерживающий JIT (just-in-time) для динамической компиляции Java-кода для HotSpot JVM, а также режим упреждающей компиляции (AOT, ahead-of-time) классов в машинный код перед запуском виртуальной машины. Компилятор был написан на Java и основан на наработках проекта Graal. Отмечается, что сопровождение компилятора требует больших трудозатрат, которые не оправдывают себя в условиях невостребованности у разработчиков.