В марте разработчикам в их привычных средах разработки пришло сообщение "New JDK version is available", что означало, что вышел очередной релиз Java 16 с открытым исходным кодом Java SE (Standard Edition) 16 и Java Development Kit 16 (JDK 16). Подготовка к выпуску окончена, и набор новых функций (JEP), который  был утвержден, теперь реализован в  JDK и опубликован в открытом доступе. Известно, что для 16-го релиза новых JEP уже не будет. А следующий, 17-й релиз выйдет в сентябре.  Ах да, что же такое JEP для новых релизов Java? Для новичка это всегда не очень понятно. Что такое JEP в превью к JDK. "Предложение по улучшению Java" (JEP). JEP - это документ, предлагающий усовершенствование базовой технологии Java. Это предложения, как правило, для улучшений, которые еще не готовы к уточнению. Как говорится в документе JEP-0, JEP могут требовать изучения новых (даже причудливых) идей. Вообще говоря, прототипирование будет необходимо для разделения жизнеспособных и нежизнеспособных идей и уточнения их до такой степени, что можно будет разработать спецификацию.     Мы предлагаем разработчикам, аналитикам, архитекторам и просто любителям Java наш краткий и далеко не самый полный обзор, чтобы получить представление о том, что поменяется в JDK 16. Что изменилось в общем? Некоторые из предстоящих основных функций JDK 16 включают одновременную обработку стека потоков для «сборки мусора», поддержку функций языка C++ 14, возможность гибкого (elastic) Metaspace для более быстрого возврата неиспользуемой памяти в операционную систему, изменения в организации процедур, новые API и инструменты, порты операционной системы, инкапсулирование начинки JDK и некоторые другие вещи. Нам бы хотелось отметить следующие знаковые вещи: Итак, игнорировать роль старых добрых Fortran и C++ перестали. Действительно, когда требуется скорость вычислений, JAVA не справится и пора это признать. Git чрезвычайно удобная вещь, незаменимая в современном процессе разработки. Разработчик JDK 16 посвятил GIT несколько JEP. Внешняя память, сборка муссора и кэш. Традиционно важные пункты для каждого нового релиза JAVA. Роль проектов на микросервисной архитектуре тредует нововведений. Где-то хорош Linux  и взаимодействие JAVA с ним бесспорно надо развивать, но в последнее время Windows также развивается и появляются серверные технологии  на ее основе. Начиная с этого релиза произвоится попытка дать разработчикам, ведущим работу в разных операционных системах удобные инструменты.  JEP 397: Изолированные классы (sealed classes) становятся еще более изолированными: Об изоляции классов речь шла ранее в JDK 15. Именно в рамках 15-го релиза были предложены и поставлены изолированные классы (sealed classes) в качестве preview feature. Напомним, что концепция изолированных классов предусматривает ограничение возможности их расширения или выполнения для других классов. Фактически это означает запрет наследоваться от данного (изолированного) класса. https://openjdk.java.net/jeps/397 Для чего: Разрешить разработчику класса или интерфейса самому контролировать, какая часть кода будет отвечать за его реализацию Предоставить более удобный и понятный способ, чем модификаторы доступа (access modifiers), для ограничения использования суперклассов. Поддержать дальнейшее развитие “паттерн матчинга” (pattern Matching), предоставив фундамент для полного анализа паттернов. Что это означает и к чему приведет? В JLS придется описывать контекстные ключевые слова (contextual keyword), которые заменят введенные ранее идентификаторы и ключевые слова типа (estricted keyword и restricted identifier). Для этого следует вводить набор изолированных и неизолированных последовательностей символов и разрешить их применять в качестве контекстуальных ключевых слов в среде разработки. Также, нужно быть готовым к тому, что компилятор будет проводить более строгую проверку при конверсии типов, в иерархии которых есть изолированные классы или интерфейсы. JEP 396: Инкапсуляция внутри JDK теперь стала строгой: Строгая инкапсуляция всех внутренних элементов JDK теперь будет по умолчанию. Ну, за исключением таких критических внутренних API, как sun.misc.Unsafe. Однако теперь можно разрешить пользователям выбирать ослабленный тип наследования deny. Речь идет об опции --illegal-access, которая до была "permit", а с 16-й JAVA становится "deny". https://openjdk.java.net/jeps/396 Для чего: Повысить безопасность и ремонтопригодность JDK, как части Project Jigsaw, и призвать разработчиков перейти от использования внутренних элементов JDK к стандартным API.Делается это для того чтобы возмоно было легко перейти к использованию дальнейших версий Java. Комментарии: Этот JEP несет в себе риск того, что существующий код Java не будет запущен. Разработчикам рекомендуется использовать инструмент jdeps для идентификации кода, который опирается на внутренние элементы JDK, и при наличии переключаться на их стандартные замены. Разработчики могут использовать существующую версию, такую как JDK 11, для тестирования существующего кода с помощью using-inlegal-access = warn для идентификации внутренних элементов, к которым осуществляется доступ с помощью отражения, -llegal-access = debug для обнаружения ошибочного кода и-inlegal-access = deny testing. Что изменилось: 1.     Доступ к защищенным членам классов и статический доступ к неэкспортированным API (sun.*, com.sun.*, jdk.internal.* и т. д.) теперь будет давать ошибку.  2.     Если код требует доступа к внутренностям JDK во время выполнения, то, чтобы он отработал на Java 16, ему теперь придется явно указывать одну из трех опций JVM: --illegal-access=permit/warn/debug: открытие всех пакетов JDK --add-opens=module/package=target-module: открытие одного пакета --add-exports=module/package=target-module: экспортирование одного пакета (только для статического доступа). EP 395: Записи: Записи были ранее введены в ответ на критику о том, что Java стала слишком громоздкой из-за большого количества формальных шаблонов или паттернов. О записях шла речь и ранее. Предварительно они были представлены в JDK 14 и JDK 15. Теперь можно свободно расширять язык программирования Java с помощью записей, которые являются классами, выполняющими функции прозрачных носителей неизменяемых данных. Записи можно рассматривать как именные кортежи. https://openjdk.java.net/jeps/395 Для чего: Запись - это объектно-ориентированная конструкция, которая выражает довольно просто агрегацию значений. Помочь разработчикам сосредоточиться на моделировании неизменяемых данных, а не на расширении вариаций их поведения. Автоматически внедрять методы, управляемые данными, такие как equals и accessors. Защитить первоначальные принципы Java, такие как номинальная типизация и совместимость с миграцией. Что изменилось: Так как какого-то более-менее внятного описания разработчик JDK никогда не предоставляет, нами опытным путем было установлено, что в Java 16 было внесено следующее изменение: теперь во внутренних классах разрешено объявлять статические члены. JEP 394: Возможность сопоставления паттернов для экземпляра: Данный JEP означает введение паттерна для оператора instanceof. Идея эта окончательно завершена в JDK 16, хотя ранее предварительно рассматривалась в релизах JDK 14 и JDK 15. https://openjdk.java.net/jeps/394 Для чего: Популярная и часто используемая логика в программировании, такая как извлечение по условию компонентов из объектов, может быть выражена более сжато и безопасно с помощью сопоставления образцов, описанных в паттернах. Что изменилось: Фактически это означает введение паттерна для оператора instanceof. JEP 393: API доступа к Foreign Memory (третий инкубатор): API доступа к Foreign Memory, который ранее инкубировался как в JDK 14, так и в JDK 15, будет повторно инкубироваться в JDK 16 со значительными улучшениями. При этом функции интерфейсов MemureSegment и MemureAddresses стали различаться более четко. По факту данный API - это API доступа к внешней памяти, который позволяет Java-программам безопасно получать доступ к памяти за пределами "Java-кучи" (heap java). Многие Java-программы получают доступ к «зарубежной памяти»  Foreign Memory, например, Ignite, mapDB, memcached, Lucene и API ByteBuf от Netty. К сожалению, Java API на данный момент не обеспечивал  удовлетворительного решения для доступа к Foreign Memory. https://openjdk.java.net/jeps/393 Для чего: Для оптимизации расходов и ухода от непредсказуемости «сбора мусора». Особенно это касается тех случаев, когда у вас в проекте много обращений к кэшированным данным. Теперь несколько процессов могут одновременно использовать память. Сериализация и десериализация содержимого памяти путем преобразования файлов в память (например, через mmap). Что изменилось Фактически это означает введение паттерна для оператора instanceof. Идея эта завершена в JDK 16, хотя ранее была предварительно рассмотрена в JDK 14 и JDK 15. JEP 392: Упаковочный инструмент теперь стал постоянным модулем: Jpackage был реализован ранее в качестве инкубационного инструмента в JDK 14, таковым он оставался и в JDK 15. С JDK 16 jpackage получает права постоянного модуля. Инструмент jpackage нужен для упаковки автономных средств Java. Многие Java-программы теперь получат доступ к foreign memory, например, Ignite, mapDB, memcached, Lucene и API ByteBuf от Netty. К сожалению, Java API так и не обеспечивает удовлетворительного решения для доступа к Foreign Memory. https://openjdk.java.net/jeps/392 Для чего: Поддерживать собственные форматы упаковки, более привычные конечным пользователям, ведущим разработку для различных операционных систем. В Windows этими форматами являются msi и exe, на macOS - pkg и dmg, а также на Linux - deb и rpm. Позволить указывать параметры времени запуска во время упаковки. Разрешить использовать API-интерфейс ToolProvider  для непосредственного вызова из командной строки. Что изменилось: jpackage получает права постоянного модуля JEP 390: Warning для value-based классов: Ситуация: объявите классы-оболочки примитивных типов (integer, double и прочее), а затем  удалите их конструкторы. Что произойдет? Вы увидите, что в JAVA 16 это приведет к новым предупреждениям, о попытке неправильной синхронизации экземпляров классов на основе значений платформы Java. https://openjdk.java.net/jeps/390 Произведена попытка создать внешний API компоновщик, который обеспечивал бы статический, доступ через Java к коду, написанному на каком-то другом языке. Этот API будет находиться на стадии инкубатора в JDK 16. Вместе с предлагаемым API доступа к Foreign Memoryчерез API внешнего компоновщика значительно упрощается методика связывания с собственными библиотеками, а также выбросом собственных ошибок. https://openjdk.java.net/jeps/389 Цель: Обеспечить простоту в использовании java. Теперь можно заменить JNI новой моделью разработки на языке чистой Java. Обеспечить поддержку языка C : первоначальный объем данного проекта направлен на то, чтобы предусмотреть высококачественную, полностью интегрированную совместимость с библиотеками C на платформах x64 и AArch64. API Foreign Linker и его реализация должны быть достаточно универсальными для размещения в дальнейшем на других платформах различной разрядности (например, 32-разрядных x86) и прочих "внешних" функций, написанных на языках, отличных от C (например, C++, Fortran). Обеспечить эффективность: International Linker API должен обеспечивать производительность, сравнимую или лучшую, чем JNI. Теперь можно включать использование функций языка C++ 14 в исходном коде JDK. Не только включать, но и предоставить четкие инструкции по использованию этих функций в коде HotSpot. https://openjdk.java.net/jeps/347 Для чего: Думаю, тут и так все ясно. Возможности C++14  уникальны для многих задач. Этот вопрос давно назрел и вот свершилось. Можно теперь делать перенос репозитория исходного кода OpenJDK Project из Mercurial (hg) в Git . https://openjdk.java.net/jeps/357  Для чего: Ожидаются преимущества в размере и доступных ресурсах через хостинг системы управления версиями. JEP 369: Миграция на GitHub: Предлагается репозиторий Host Git для сообщества OpenJDK на GitHub. https://openjdk.java.net/jeps/369  Для чего: Чтобы можно было перемещать все проекты OpenJDK с одним исходным кодом на GitHub вместе с JEP 357 (Migrate from Mercurial to Git) и включить все версии JAVA 11 и более поздние обновления JDK, а также их более поздние модернизации. JEP 376: ZGC: параллельная обработка стека потоков: Переход потокового стека ZGC от safepoints к "параллельной" фазе. https://openjdk.java.net/jeps/376 Z Garbage Collector (ZGC) предназначен для того, чтобы оставить все проблемы с масштабируемостью в HotSpot при сборке мусора ушедшими в прошлое. На сегодняшний день операции GC, масштабирующие размер JAVA кучи и размер метапространства, были перенесены из операций с safepoints  в "параллельные" фазы. Это включило в себя: маркировку, перемещение, обработку ссылок, а также класс разгрузки и обработку большинства корней. Единственными операциями, все еще выполняемыми в safepoints GC, являются операции с подмножествами обработки "корня" и операции маркировки окончания с привязкой по времени. Для чего: Удалить обработку стека потоков из safepoints ZGC. Сделать обработку стека удобной и упорядоченной. Удалить всю лишнюю корневую обработку для каждого потока из safepoints ZGC. JEP 386: Alpine Linux Port: Порт JDK к архитектурам x64 и AArch64 в Alpine Linux и других дистрибутивах Linux, использующих библиотеку musl. https://openjdk.java.net/jeps/386 Musl - это реализация для систем на базе Linux стандартных библиотечных функций, описанных в стандартах ISO C и POSIX. Несколько дистрибутивов Linux, включая Alpine Linux и OpenWrt, основаны на musl. Из-за небольшого размера образа Alpine Linux широко используется в облачных развертываниях, в микросервисных системах и средах на основе контейнеров. Размер образа Docker для Linux меньше 6 МБ. В таких средах использование Java в нестандартных средах позволит Tomcat, Jetty, Spring и другим популярным фремворкам эффективнее работать в этих средах.  Цель данного JEP - более эффективно возвращать в используемую операционную систему невостребованную оперативную память, уменьшить тем самым размер  Metaspace и упроcтить тем самым код. Ранее при использовании Metaspace возникали проблемы с высоким уровнем задействованной памяти вне JAVA кучи. Предложение включает схему распределения на основе Buddy для замены текущего распределителя памяти и включает алгоритм разделения памяти на разделы для удовлетворения запросов памяти. https://openjdk.java.net/jeps/387 Что изменилось: Для того чтобы полностью использовать гибкость, обеспечиваемую Buddy Allocation, память Metaspace будет скомпонована в кластеры одинакового размера, которые могут использоваться независимо друг от друга. Теперь можно подключать JDK к платформе Windows/ AArch64. https://openjdk.java.net/jeps/388 Windows/ AArch64 стала, как платформа. играть более значительную роль  с появлением нового серверного оборудования на основе AArch64 (ARM64). Основной целью этого JEP является включение порта в основное хранилище JDK, хотя само портирование остается в основном полным.