Публикация

Что нового в Java 17?

Очередная серия нововведений и изменений Java не заставила нас ждать и уже представила список довольно интересных изменений.

В сентябре 2021 года планируется официальный релиз JDK 17, где будет представлен весь список нововведений о которых речь пойдет ниже. Этот материал может быть изменен до момента официально релиза в сентябре.

Установить JDK 17 можно уже по ссылке или с использованием SDKMan:

sdk install java 17.ea.30-open

А теперь подробней о каждом JEP и как он повлиял на Java 17.

JEP 306: Restore Always-Strict Floating-Point Semantics

В 90х была проблема связанная с семантикой операций с плавающей запятой при взаимодействии Java с JVM работающей на базе популярной архитектуры x86, которая имела некоторые проблемы связанные с набором команд процессора с плавающей запятой.

И чтобы соответствовать точной семантики с плавающей запятой в Java SE 1.2 было решено пересмотреть устройство семантики с плавающей запятой по умолчанию для x86, что требовало дополнительных накладных расходов.

Однако, позже было разработано расширение SSE2 (Streaming SIMD Extensions 2), которое поставлялось в процессорах Pentium 4 и более поздних версиях. Они могли поддерживать строгие операции с плавающей запятой JVM без чрезмерных накладных расходов.

И поскольку Intel и AMD уже давно поддерживает SSE2 которые обеспечивают естественную поддержку строгой семантики с плавающей запятой, то потребности в поддержки семантики с плавающей запятой отличной от строгой больше нет. И в JEP 306 было решено ее убрать.

JEP 356: Enhanced Pseudo-Random Number Generators

В этом JEP представлен новый интерфейс RandomGenerator и реализации для генераторов псевдослучайных чисел (PRNG):

  • SplittableRandomGenerator расширяет RandomGenerator, а также предоставляет методы split и splits, которые позволяют пользователю создавать новые RandomGenerator из уже существующего RandomGenerator, который обычно дает статистически независимые результаты.
  • JumpableRandomGenerator расширяет RandomGenerator, а также предоставляет методы jump и jumps, которые позволяют продвигаться вперед на небольшое количество генераций.
  • LeapableRandomGenerator расширяет RandomGenerator, а также предоставляет методы leap и leaps, которые позволяют продвигаться вперед на большое количество генераций.
  • ArbitrarilyJumpableRandomGenerator расширяет RandomGenerator, а также предоставляет методы jump и jumps, которые позволяют указать количество произвольных генераций.

Основная идея состоит в том, чтобы упростить переключение между различными алгоритмами PRGN, удалить дублирующий код в существующих PRGN, обеспечить лучшую поддержку stream-based программирования и при этом всем сохранить текущее поведение java.util.Random.

JEP 382: New macOS Rendering Pipeline

В сентябре 2018 года Apple отказалась от OpenGL в macOS 10.14. А так как в Java 2D внутреннее устройство pipeline рендеринга полностью зависит от OpenGL, появилась необходимость в новой реализации Java 2D API.

Так как Apple позиционирует Metal фреймворк заменой OpenGL, который в свою очередь обладает превосходной производительностью, было решено для новой реализации поддержки Java 2D API взять именно Metal фреймворк.

И в JDK 17 для macOS выше 10.14 Java 2D будет использовать Metal фреймворк.

JEP 391: macOS/AArch64 Port

Так как в Apple было принято решение на долгосрочный переход компьютеров серии Macintosh c процессоров архитектуры x64 на AArch64, то для JDK появляется необходимость в портировании как ранее было сделано для Linux на базе AArch64.

Значит ли это, что Java не будет работать на AArch64? Нет, так как Apple предоставила Rosetta 2, которая одноразово переведет байт код работающий под x64 на новый, который будет понимать AArch64, но момент ретрансляции займет дополнительное время и ресурсы.

Этот JEP позволяет выполнять Java код нативно на базе AArch64 без использования Rosetta 2.

JEP 398: Deprecate the Applet API for Removal

Applet API уже довольно давно устарел и почти все популярные браузеры удалили его поддержку либо объявили о его скором удалении.

В Java 9 в JEP 289 Applet API был помечен как устаревший но пока еще без пометки на удаление в будущих версиях. В Java 17 Applet API помечен на удаление и будет удален в последующих релизах Java.

JEP 403: Strongly Encapsulate JDK Internals

В Java 16 был установлен параметр по умолчанию, который позволял контролировать возможность доступа к внутренним API и пакетам JDK.

В Java 17 этот параметр был удален и возможность ослабить строгую инкапсуляцию внутренних частей полностью отсутствует.

JEP 406: Pattern Matching for switch (Preview)

В Java 16 была добавлен Pattern Matching для оператора instanceof подробней можно ознакомится тут. Java 17 представляет на предварительный просмотр Pattern Matching для конструкции switch.

Например, ранее мы бы написали следующий код так:

static String formatter(Object o) {
  String formatted = "unknown";
  if (o instanceof Integer i) {
    formatted = String.format("int %d", i);
  } else if (o instanceof Long l) {
    formatted = String.format("long %d", l);
  } else if (o instanceof Double d) {
    formatted = String.format("double %f", d);
  } else if (o instanceof String s) {
    formatted = String.format("String %s", s);
  }

  return formatted;
}

Но для решения подобного рода задач в разы приятней и лучше подошла бы конструкция switch, что Java 17 нам и предложила:

static String formatterPatternSwitch(Object o) {
  return 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();
  };
}

Также ранее switch бросал исключение в случае, когда передаваемый параметр был null, и чтобы исключить такую возможность мы делали проверку на null:

static void testFooBar(String s) {
  if (s == null) {
    System.out.println("oops!");
    return;
  }
  switch (s) {
    case "Foo", "Bar" -> System.out.println("Great");
    default           -> System.out.println("Ok");
  }
}

Теперь же, все проще и необходимости проверять параметр на null не нужен:

static void testFooBar(String s) {
  switch (s) {
    case null         -> System.out.println("Oops");
    case "Foo", "Bar" -> System.out.println("Great");
    default           -> System.out.println("Ok");
  }
}

Больше примеров использования Pattern Matching для switch можно найти тут.

JEP 407: Remove RMI Activation

В Java 15 механизм активации RMI был помечен как устаревший и возможен к удалению в будущих версиях. И в Java 17 в JEP 407 он был полностью удален.

JEP 409: Sealed Classes

В Java 16 был представлен второй предварительный просмотр Sealed классов и вот в Java 17 они выходят со стадии предварительного просмотра и становятся частью JDK начиная с 17 версии.

Более подробно с новой функциональностью вы можете познакомится тут.

Sealed классы или интерфейсы ограничивают доступ к их расширению или реализации посредством явного указания классов/интерфейсов которым это разрешено.

public sealed class Animal permits Dog, Cat, Monkey { ... }

JEP 410: Remove the Experimental AOT and JIT Compiler

В Java 9 в качестве экспериментальной функции был добавлен инструмент jaotc позволяющий выполнять ahead-of-time (AoT) compilation позволяющий ускорить запуск Java приложений. Инструмент использует компилятор Graal.

По причине малой активности использования данного инструмента и больших усилий на его поддержку было принято решение удалить его с JDK 17.

JEP 411: Deprecate the Security Manager for Removal

В релизе Java 1.0 был добавлен Security Manager, который уже длительное время никем не используется. В Java 17 Security Manager помечен как устаревший и будет удален в последующих версиях вместе с Applet API.

JEP 412: Foreign Function & Memory API (Incubator)

Этот JEP является эволюцией двух ранее созданных API-интерфейсов: Foreign-Memory Access API и Foreign Linker API, которые ранее был представлены в Java 14, 15 и 16.

JEP 414: Vector API (Second Incubator)

Первый предварительный просмотр был представлен в Java 16. Java 17 представляет к нашему вниманию второй предварительный просмотр, где Vector API был улучшен с точки зрения производительности и реализации, включая улучшения для преобразования байтовых векторов в логические массивы из них.

JEP 415: Context-Specific Deserialization Filters

Десериализация ненадежных данных - операция, которая по своей сути рискованна, потому что содержимое входящих потоков данных во многих случаях получается через неизвестного или не прошедшего проверку подлинности клиента.

Ключом к предотвращению атак сериализации является запрет десериализации экземпляров произвольных классов, что предотвращает выполнение их методов прямо или косвенно. Злоумышленник может запустить код любого класса с плохими намерениями, тщательно сконструировав поток.

В Java 9 были представлены фильтры десериализации, чтобы код приложения и библиотеки мог проверять входящие потоки данных перед их десериализацией. Такой код предоставляет логику проверки в виде java.io.ObjectInputFilter, когда он создает поток десериализации.

Так вот каждый раз, когда создается ObjectInputStream, его фильтр для каждого потока инициализируется как статический фильтр для всей JVM и при желании этот фильтр для каждого потока позже может быть изменен на другой фильтр.

В этом JEP представляется настраиваемая фабрика фильтров для всего JVM. Каждый раз, когда создается ObjectInputStream, его фильтр для каждого потока инициализируется значением, возвращаемым путем вызова статической фабрики фильтров для всей JVM.

Таким образом, эти фильтры являются динамическими и зависят от контекста, в отличие от единственного статического фильтра десериализации для всей JVM. Для обратной совместимости, если фабрика фильтров не задана, встроенная фабрика возвращает статический фильтр для всей JVM, если он был настроен.

Источники

Опубликовано: 14 июля 2021 г.Просмотров: 198

Комментарии

Мы не даем слово анониму 😶
Войдите, пожалуйста.

Еще никто не комментировал эту публикацию 🤔