Вышла общедоступная версия Java 17. В этот релиз попало более 2700 закрытых задач и 14 JEP'ов. Изменения API можно посмотреть по этой ссылке. Ссылки на скачивание: Перечислим JEP'ы, которые попали в Java 17. Теперь все выражения с плавающей точкой вычисляются строго на всех платформах, и разницы между строгой семантикой и семантикой по умолчанию больше нет (как это было до Java 1.2). Таким образом, ключевое слово strictfp больше не имеет эффекта, и при его использовании выдаётся предупреждение: «Запечатанные» классы после двух preview итераций в Java 15 и Java 16 наконец-то стали стабильной синтаксической конструкцией и больше не требуют флага --enable-preview. Различий по сравнению с Java 16 нет. Напомним, ключевым слово sealed можно пометить класс или интерфейс, если нужно ограничить список его наследников. Список можно указать явно, перечислив все наследники с помощью ключевого слова permits, либо он выведется неявно компилятором из всех задекларированных наследников в текущем исходном файле. Появилась новая синтаксическая конструкция в режиме preview, существенно расширяющая возможности оператора switch: теперь оператор switch поддерживает не только простые тесты на равенство с константами примитивов, перечислений и строк, но и тесты по паттернам. Простейшие паттерны это паттерны по типу: Паттерны могут снабжаться условиями путём добавления охранных паттернов: Также добавлена поддержка матчинга null с помощью отдельной метки null: Ветки null и default можно объединять друг с другом: Все switch с паттернами должны быть исчерпывающими (даже если это switch statement, а не switch expression): Чтобы пример выше стал компилироваться, нужно либо добавить ветку default, либо тотальный паттерн (в данном случае case Object obj). Старый switch statement можно продолжать делать неисчерпывающим, однако это может измениться в будущем. Новый switch очень хорошо взаимодействует с sealed классами, поскольку круг подтипов является ограниченным, а это значит, что ветка default не является необходимой, если перечислены все возможные случаи: На этом беглое рассмотрение паттерн-матчинга для switch мы закончим, а про другие возможности и нюансы можно почитать на странице JEP. В Java 17 появился новый пакет java.util.random с новыми интерфейсами и реализациями генераторов псевдослучайных чисел. Наверху иерархии новый интерфейс RandomGenerator, который является родителем как новых генераторов и специализаций (SplittableRandomGenerator, JumpableRandomGenerator, LeapableRandomGenerator, ArbitrarilyJumpableRandomGenerator), так и старых классов (Random, ThreadLocalRandom, SplittableRandom). Таким образом, алгоритмы генерации чисел теперь стали более взаимозаменяемыми: Кроме того, список генераторов ограничен не только теми, что предоставлены самим JDK, но является расширяемыем: предоставлять свои или сторонние реализации можно через механизм ServiceLoader. API аплетов, которое стало deprecated в Java 9, теперь стало помечено как подлежащее окончательному удалению. Таким образом, существующий код, который использует классы из Applet API (java.applet.Applet, javax.swing.JApplet и т.д.), может перестать работать на одной из следующих версий Java (но всё ещё продолжит работать на Java 17). Механизм RMI Activation, который стал deprecated в Java 15, теперь удалён окончательно. RMI Activation был частью RMI, которая использовалась в чрезвычайно малом количестве приложений и фактически устарела. Для того чтобы избежать дорогой поддержки никому не нужного механизма, было принято решение его полностью удалить. Security Manager стал помечен как подлежащий удалению. В одной из будущих версий его планируется удалить окончательно. Аннотацию @Deprecated(forRemoval=true) получили 10 классов и 10 методов из стандартной библиотеки Java. Среди них java.lang.SecurityManager, java.security.Policy, java.lang.System::setSecurityManager, java.lang.System::getSecurityManager, java.lang.Thread::checkAccess и другие. Кроме того, при вызове метода System.setSecurityManager() во время исполнения будет выдаваться предупреждение: Также предупреждение будет выдаваться при установке Security Manager через аргументы командной строки указанием свойства java.security.manager: Начать отказ от Security Manager было решено по причине того, что он слабо отвечает современным требованиям безопасности и всё меньше и меньше пользуется спросом при разработке новых Java-приложений, но цена его поддержки остаётся очень высокой. У него хрупкая модель разрешений, сложная программная модель, и он приносит большие накладные расходы по производительности. Foreign Memory API, который побывал в Java 14, 15, 16 в инкубационном статусе, и Foreign Linker API, появившийся в Java 16, теперь объединены в один Foreign Function & Memory API, и он всё ещё остаётся в инкубационном статусе в модуле jdk.incubator.foreign. Векторное API, которое появилось в Java 16 в инкубационном статусе, всё ещё остаётся в этом статусе в модуле jdk.incubator.vector. Фильтры десериализации, которые появились в Java 9 для контроля десериализации из ненадёжных источников данных, стали более гибкими благодаря введению фабрики фильтров. Если раньше возможно было только указывать фильтр индивидуально для каждого объекта ObjectInputStream или использовать один глобальный статический фильтр для всей виртуальной машины, то сейчас можно указать статическую фабрику фильтров, которая для каждой операции десериализации будет возвращать нужный фильтр, подходящий для данного контекста. Фабрику фильтров можно установить через метод ObjectInputFilter.Config::setSerialFilterFactory, либо через аргументы командной строки, передав имя класса фабрики в свойство jdk.serialFilterFactory. Реализован новый конвейер рендеринга на основе современного Apple Metal API, который был создан с целью заменить устаревший Apple OpenGL API. Новый конвейер сосуществует со старым, который пока что остаётся включённым по умолчанию, но если OpenGL не работает, то запускается новый. Таким образом, Java 17 полностью готова к запуску на будущих версиях macOS, где OpenGL API будет окончательно удалён. Также новый конвейер можно включить явно, указав опцию -Dsun.java2d.metal=true. OpenJDK портирован на архитектуру macOS/AArch64, и теперь список дистрибутивов OpenJDK и Oracle JDK пополнился сборками для Apple M1. Инкапсуляция внутренних API, которая была введена в Java 9 и была выключена по умолчанию в Java 16, но всё ещё могла быть включена одной опцией командной строки, теперь не может быть включена одной опцией: Таким образом, доступиться до внутренностей JDK (sun.*, com.sun.*, jdk.internal.* и т.д.) теперь можно только путём явного перечисления всех необходимых пакетов с помощью опций --add-opens или --add-exports. Изменения не касаются критического API в модуле jdk.unsupported: классы в пакетах sun.misc и sun.reflect остаются доступными без флагов. В будущем опция --illegal-access будет удалена окончательно, и при её использовании будет ошибка старта. Удалены экспериментальные ahead-of-time и just-in-time Graal компиляторы. Такое решение было принято из-за сложности поддержки и их малой используемости (те, кому они нужны, используют GraalVM). По факту этих компиляторов уже не было в сборках JDK 16 от Oracle. Удалению подлежали три модуля: jdk.aot, jdk.internal.vm.compiler и jdk.internal.vm.compiler.management. Модуль JVMCI (jdk.internal.vm.ci) остался, чтобы у разработчиков всё ещё оставалась возможность использовать внешний JIT-компилятор. Предыдущая версия OpenJDK с Long Term Support, Java 11, вышла ровно 3 года назад, хотя кажется, что она вышла совсем недавно, практически вчера. Но вот уже вышло 5 версий (12, 13, 14, 15, 16) и мы не успели опомниться, как подоспела следующая LTS-версия, Java 17. Для тех, кто будет переходить с 11, Java 17 будет достаточно большим апгрейдом. Если сложить все релизы с 12 по 17, то в сумме появилось 5 больших языковых конструкций: выражения switch, блоки текста, записи, паттерн-матчинг для instanceof и sealed классы. Появилось очень много интересного API, сделано много улучшений производительности, оптимизировано потребление памяти, уменьшено время старта JVM. Очень много чего было удалено, поэтому могут возникнуть некоторые трудности при миграции. Следующими большими шагами для Java будет завершение реализации проектов Valhalla, Loom и Panama, а также дальнейшие языковые улучшения в проекте Amber. Увидим ли мы всё это в следующей LTS-версии? Узнаем через 2 года.