[Java] Вышла Java 16

Автор Сообщение
news_bot ®

Стаж: 6 лет 2 месяца
Сообщений: 27286

Создавать темы news_bot ® написал(а)
16-Мар-2021 20:30

Вышла 16-я версия платформы Java SE. В этот релиз попало около двух с половиной тысяч закрытых задач и 17 JEP'ов. Изменения API можно посмотреть здесь. Release notes здесь.
Уже сейчас доступны для скачивания дистрибутивы Oracle JDK и OpenJDK.
JEP'ы, которые попали в Java 16, мы разобьём на четыре категории: язык, API, JVM и инфраструктура.
Язык
Паттерн-матчинг для оператора instanceof (JEP 375)
Оператор instanceof с паттерн-матчингом, который появился в Java 14 и перешёл во второе preview в Java 15, теперь стал стабильной синтаксической конструкцией и больше не требует флага --enable-preview. Паттерн-матчинг мы подробно рассматривали в этой статье, и с того момента в него было внесено два изменения:
Во-первых, переменные паттернов теперь не являются неявно финальными:
if (obj instanceof String s) {
    s = "Hello"; // OK в Java 16, ошибка в Java 15
}

Во-вторых, если тип выражения, известный на этапе компиляции, является подтипом проверяемого типа, то теперь это ошибка компиляции:
String str = ...
if (str instanceof String s) { // Oшибка в Java 16, OK в Java 15
}

Записи (JEP 395)
Ещё одна синтаксическая конструкция, которая стала стабильной – это записи. Она также была в режиме preview в Java 14 и Java 15. Записи мы также подробно рассматривали ранее. В Java 16 было внесено следующее изменение: теперь во внутренних классах разрешено объявлять статические члены:
public class Outer {
    public class Inner {
        // OK в Java 16, ошибка в Java 15
        static void main(String[] args) {
        }
        // OK в Java 16, ошибка в Java 15
        record Point(int x, int y) {
        }
    }
}

sealed классы (второе preview) (JEP 397)
«Запечатанные» классы, которые появились в Java 15 в режиме preview, остаются в этом статусе. Их мы рассматривали в этой статье. Изменения по сравнению с прошлой версией следующие:
  • Теперь в спецификации языка Java появилось понятие contextual keyword взамен старым понятиям restricted keyword и restricted identifier, и одними из таких contextual keywords стали sealed, non-sealed и permits.
  • Компилятор теперь производит более строгие проверки при конверсии типов, в иерархиях которых есть sealed классы:
    sealed interface Sealed {
    }
    final class Impl implements Sealed {
        void f(Runnable r) {
            Sealed s = (Sealed) r; // error: incompatible types
        }
    }
  • Метод Class.permittedSubclasses() переименован в Class.getPermittedSubclasses().

JVM
Строгая инкапсуляция внутренностей JDK по умолчанию (JEP 396)
Инкапсуляция внутренних API JDK, которая была введена в Java 9, теперь стала строгой: если в Java 9-15 значение опции --illegal-access было по умолчанию permit, то с Java 16 она становится deny. Это значит, что рефлективный доступ к защищённым членам классов и статический доступ к неэкспортированным API (sun.*, com.sun.*, jdk.internal.* и т.д.) теперь будет выбрасывать ошибку.
Если код требует доступа к внутренностям JDK во время выполнения, то чтобы он продолжал работать на Java 16, теперь придётся явно указывать одну из трёх опций JVM:
  • --illegal-access=permit/warn/debug: открытие всех пакетов JDK
  • --add-opens=module/package=target-module: открытие одного пакета
  • --add-exports=module/package=target-module: экспортирование одного пакета (только для статического доступа)

В будущем опция --illegal-access может быть удалена окончательно. Начиная с Java 16, при её использовании выдаётся предупреждение: Option --illegal-access is deprecated and will be removed in a future release.
Изменения не касаются критического API в модуле jdk.unsupported: классы в пакетах sun.misc и sun.reflect остаются доступными без флагов.
Warnings for Value-Based Classes (JEP 390)
Классы-обёртки примитивных типов (Integer, Double, Character и т.д.) теперь относятся к категории value-based классов, и их конструкторы, которые ранее стали deprecated в Java 9, теперь помечены как deprecated for removal.
Понятие value-based классов появилось в спецификации API Java 8. Такие классы являются неизменяемыми, создаются только через фабрики, и в их использовании не должны использоваться операции, чувствительные к identity: сравнение на ==, синхронизация, identityHashCode() и т.д. Value-based классы являются кандидатами для миграции на примитивные классы в рамках проекта Valhalla, который сейчас находится в стадии активной разработки.
При синхронизации на объектах value-based классов теперь будет выдаваться предупреждение во время компиляции:
Double d = 0.0;
synchronized (d) { // warning: [synchronization] attempt to synchronize on an instance of a value-based class
}

Также можно включить проверки синхронизации на value-based объектах во время выполнения с помощью флагов JVM:
  • -XX:+UnlockDiagnosticVMOptions -XX:DiagnoseSyncOnValueBasedClasses=1: при попытке синхронизации будет фатальная ошибка.
  • -XX:+UnlockDiagnosticVMOptions -XX:DiagnoseSyncOnValueBasedClasses=2: при попытке синхронизации будет предупреждение.

ZGC: Concurrent Thread-Stack Processing (JEP 376)
Обработка стеков потоков в сборщике мусора ZGC теперь перенесена из safepoints в конкурентную фазу. Это позволило ещё сильнее уменьшить паузы сборщика мусора.
Unix-Domain Socket Channels (JEP 380)
Добавлена поддержка сокетов доменов Unix в socket channel и server-socket channel API. Такие сокеты используются для межпроцессного взаимодействия внутри одного хоста, и в них не используются сетевые соединения, что делает такое взаимодействие более безопасным и эффективным. Сокеты доменов Unix с недавних пор поддерживаются в Windows 10 и Windows Server 2019.
Elastic Metaspace (JEP 387)
Metaspace (пространство JVM, в котором хранятся метаданные классов) переработан для более эффективной отдачи неиспользуемой памяти обратно операционной системе и меньшего потребления памяти вне кучи в целом. Такое улучшение может быть полезно для приложений, которые интенсивно загружают и выгражают классы посредством большого количества загрузчиков классов.
Alpine Linux Port (JEP 386)
JDK теперь портирован на Alpine Linux и другие дистрибутивы Linux, которые используют musl в качестве реализации стандартной библиотеки C. Alpine Linux популярен в облаках, микросервисах и контейнерах благодаря своему маленькому размеру образа. Новый порт позволит нативно запускать JDK в этих окружениях.
Windows/AArch64 Port (JEP 388)
JDK также портирован на архитектуру Windows/AArch64. Это позволит запускать Java на компьютерах с Windows on ARM, которые в последнее время набирают популярность.
API
Новые методы в Stream
Хотя для этих двух новых методов в интерфейсе java.util.stream.Stream нет отдельного JEP, хочется упомянуть их здесь, так как это довольно заметное изменение.
Первый метод – это Stream.toList(). Этот метод собирает содержимое Stream в неизменяемый список и возвращает его. При этом, в отличие от Collectors.toUnmodifiableList(), список, который возвращается из Stream.toList(), толерантен к null-элементам.
Второй метод – это Stream.mapMulti() (и примитивные специализации). Это метод является императивным аналогом метода Stream.flatMap(): если flatMap() принимает функцию, которая для каждого элемента должна вернуть Stream, то mapMulti() принимает процедуру с двумя параметрами, где первый параметр – это текущий элемент, а второй – Consumer, в который кладутся значения. Пример:
IntStream.rangeClosed(1, 10).mapMulti((i, consumer) -> {
    for (int j = 1; j <= i; j++) {
        consumer.accept(j);
    }
}); // Возвращает 1, 1, 2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4, 5, ...

Инструмент упаковки (JEP 392)
Инструмент создания самодостаточных приложений jpackage, который появился в Java 14 в инкубационном статусе, теперь стал постоянным модулем.
Vector API (Incubator) (JEP 338)
Появился новый инструментарий для преобразования векторных вычислений в SIMD-инструкции процессора (x64 и AArch64). Векторное API позволит разработчику контролировать процесс компиляции и не полагаться на автовекторизацию, которая в JVM является ограниченным и хрупким механизмом. Явная векторизация может применяться в таких областях как машинное обучение, линейная алгебра, криптография и др.
API находится в инкубационном модуле jdk.incubator.vector.
Foreign Linker API (Incubator) (JEP 389)
Ещё одно новое API, которое появилось в результате работы над проектом Panama – это Foreign Linker API. Это инструментарий для статического доступа к нативному коду из Java, созданный для замены JNI: он должен быть более простым в использовании, более безопасным и желательно более быстрым.
Про Foreign API делал доклад Владимир Иванов из Oracle.
Foreign-Memory Access API (Third Incubator) (JEP 393)
API для доступа вне кучи Java, которое появилось в Java 14, остаётся в инкубационном статусе с некоторыми изменениями.
Инфраструктура
Enable C++14 Language Features (JEP 347)
Кодовая база JDK до Java 16 использовала стандарты C++98/03. При этом с Java 11 код стал собираться версией с более новым стандартом, однако в нём всё ещё нельзя было использовать возможности стандарта C++11/14. Теперь же часть из этих возможностей использовать можно: в гиде по стилю HotSpot определён список возможностей C++11/14, которые можно использовать и которые нельзя.
Migrate from Mercurial to Git (JEP 357) и Migrate to GitHub (JEP 369)
Совершён переход репозиториев JDK на Git и GitHub. Миграция была полностью завершена в сентябре 2020 года, и разработка Java 16 уже полностью велась в новом репозитории.
Переход на GitHub облегчил процесс принятия изменений контрибьюторами. Теперь изменения предлагаются через привычные большинству пользователей пулл-реквесты, и большая часть процесса автоматизирована с помощью команд и ботов. Подробнее про процесс можно прочитать на странице проекта Skara.
Также сейчас обсуждается переход на Git более старых версий JDK: jdk11u и, возможно, jdk8u.
Java 16 является STS-релизом, у которого выйдет только два обновления.
Если вы не хотите пропускать новости о Java, то подписывайтесь на Telegram-канал miniJUG
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_java, #_java, #_jdk, #_openjdk, #_java16, #_java15, #_java14, #_java11, #_java9, #_java8, #_sealed, #_record, #_zgc, #_panama, #_valhalla, #_simd, #_patternmatch, #_alpinelinux, #_musl, #_git, #_github, #_java
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 02-Май 10:15
Часовой пояс: UTC + 5