Публикация

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

Март 2020 выходит Java 14 с довольно большим списком изменений и нововведений, которые не могут заставить пропустить их мимо глаз.

JEP 358: Helpful NullPointerExceptions

Было улучшено удобство использования NullPointerExceptions предоставляющее дополнительную информацию о том, в каком поле или операции возникло исключение.

К примеру у нас есть следующий код:

final String[] st = new String[1];
st[0].length();

Ранее мы бы увидел следующее сообщение об ошибке:

Exception in thread "main" java.lang.NullPointerException
	at Java14JEP358.main(JEP358.java:11)

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

В Java 14 мы будем видеть сообщение об ошибке NPE более детально поясняющее что и в каком месте было null:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "<local0>[0]" is null
	at Java14JEP358.main(JEP358.java:11)

JEP 345: NUMA-Aware Memory Allocation for G1

Non-Uniform Memory Access (NUMA) - это метод настройки кластера микропроцессоров в многопроцессорной системе, чтобы они могли совместно использовать память локально, повышая производительность и возможность расширения системы.

В Java 14 предусмотрена функция выделения памяти с учетом NUMA для повышения производительности G1 на больших машинах.

Куча G1 организована как набор областей фиксированного размера. Регион обычно представляет собой набор физических страниц, хотя при использовании больших страниц (через -XX:+UseLargePages) несколько регионов могут составлять одну физическую страницу.

Если указана опция +XX:+UseNUMA, то при инициализации JVM регионы будут равномерно распределены по общему количеству доступных узлов NUMA.

JEP 349: JFR Event Streaming

Java 14 предоставила API, с помощью которого данные, собранные JDK Flight Recorder (JFR), будут непрерывно отслеживать внутренние и внешние приложения.

Тот же набор событий может быть записан, как в non-streaming режиме, с накладными расходами менее 1%, если это возможно. Следовательно, потоковая передача событий будет выполняться одновременно с потоковой передачей.

Пакет jdk.jfr.consumer в модуле jdk.jfr расширен функциональностью асинхронной подписки на события.

JEP 352: Non-Volatile Mapped Byte Buffers

FileChannel API был улучшен для поддержки создания сопоставленных байтовых буферов в энергонезависимой памяти (persistent memory). Эта функция поддерживается только на платформах Linux/x64 и Linux/AArch64.

JEP 361: Switch Expressions (Standard)

Switch Expressions, который был добавлен как предварительный просмотр в Java 13, становится частью Java 14. Более детально вы можете ознакомится в "Что нового в Java 13?".

JEP 362: Deprecate the Solaris and SPARC Ports

Solaris/SPARC, Solaris/x64 и Linux/SPARC порты устарелии будут удалены в будущих релизах Java.

JEP 363: Remove the Concurrent Mark Sweep (CMS) Garbage Collector

CMS Garbage Collected был помечен как устаревший в Java 9 и теперь удален в Java 14.

JEP 364: ZGC on macOS

ZGC был представлен в Java 11, но поддержка была только для Linux. В Java 14 представлена поддержка и для macOS.

JEP 365: ZGC on Windows

Также как и JEP 364 была представлена поддержка ZGC для Windows (начиная с версии после 1803).

JEP 366: Deprecate the ParallelScavenge + SerialOld GC Combination

Из-за небольшого использования и больших усилий по обслуживанию Parallel Scavenge и SerialOld GC были помечены как устаревшие.

JEP 367: Remove the Pack200 Tools and API

Набор инструментов Pack200 и API которые были помечены как устаревшие в Java 11 были удаленны в Java 14.

JEP 305: Pattern Matching for instanceof (Preview)

Java 14 представила первый предварительный просмотр Pattern Matching для instanceof, который позволяет преобразовать проверяемы тип и сразу же его использовать.

Как было до Java 14:

Object obj = ...;
if (obj instanceof String) {
	String st = (String) obj;
  ...
}

То с Pattern Matching мы можем вынести нашу переменную String st сразу в наше условие и использовать его в нем:

Object obj = ...;
if (obj instanceof String st) {
  ...
}

JEP 359: Records (Preview)

Также представлен новое ключевое слово record, пока в предварительном просмотре, которое позволяет описывать дата классы у которого все поля final и все шаблонные методы getters, setters, toString, hashCode и equals и т.д. будут создаваться автоматически.

К примеру ранее мы создавали дата класс так:

class Person {
    private String firstName;
    private String lastName;

    Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public int hashCode() { ... }
    public String toString() { ... }
}

То используя record мы получаем следующее:

record Person(String firstName, String lastName) {}

JEP 368: Text Blocks (Second Preview)

Это второй предварительный просмотр новой возможности писать многострочные строки в Java. Первы предварительный просмотр был представлен в Java 13.

В Java 14 была добавлена возможность описывать строку в несколько строк но при этом оставлять ее единой строкой \, а также добавлять пробел используя \s:

String st = """
        This is first line\
        which is continuing as a single line with a space here "\s"
""";

> This is first line which is continuing as a single line with a space here " "

JEP 343: Packaging Tool (Incubator)

Этот инструмент был добавлен в инкубатор и предоставляет новый пакет инструментов jpackage для создания установочного пакета для конкретной платформы из вашего Java приложения.

А именно создавать файлы с расширением deb или rpm для Linux, pkg или deb для macOS или msi или exe для Windows.

К примеру у нас есть финально собранный jar файл содержащий всего один класс Main выводящий сообщение в консоль "Hello bcode community!". Чтобы создать установочный пакет мне нужно выполнить:

jpackage --name helloapp --input app --main-jar helloapp.jar --main-class Main

После чего будет создан установочный пакет содержащий мое приложение с расширение вашей платформы, в моем случае это pkg для macOS.

JEP 370: Foreign-Memory Access API (Incubator)

Foreign-Memory Access API представлен в инкубаторном состоянии и обеспечивает эффективный доступ к сегментам собственной памяти из кучи JVM вне кучи.

В примере ниже выделяется 1 Кб памяти из кучи и выводится ее базовый адрес.

try (MemorySegment segment = MemorySegment.allocateNative(1024)) {
  MemoryAddress base = segment.baseAddress();
  System.out.println(base);
}

На что мы получим следующее сообщение:

WARNING: Using incubator modules: jdk.incubator.foreign
MemoryAddress{ region: MemorySegment{ id=0x45f84202 limit: 1024 } offset=0x0 }

Чтобы использовать этот сегмент памяти, следует использовать доступ к памяти VarHandle:

final VarHandle varHandle = MemoryHandles.varHandle(int.class, ByteOrder.nativeOrder());

try (MemorySegment segment = MemorySegment.allocateNative(1024)) {
  MemoryAddress base = segment.baseAddress();
  varHandle.set(base, 1024);
  System.out.println(varHandle.get(base));
}

Что сохранит 1024 байта int в основании сегмента памяти вне кучи.

Опубликовано: 28 апреля 2021 г.Просмотров: 105

Комментарии

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

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