Особенности Java 14

Соблюдая традицию шестимесячного цикла, после выпуска Java 13 17 сентября 2019 года, Java 14, еще одна версия без долгосрочной поддержки, запланирована к выпуску 17 марта 2020 года.

Особенности Java 14

Вот список особенностей Java 14:

  • Выражения переключателя (Стандарт) – JEP 361
  • Проверка шаблонов для instanceof (Предварительный просмотр) – JEP 305
  • Полезные NullPointerExceptions – JEP 358
  • Записи (Предварительный просмотр) – JEP 359
  • Многострочные строки (Второй предварительный просмотр) – JEP 368
  • Инструмент упаковки (Инкубатор) – JEP 343
  • Выделение памяти с учетом NUMA для G1 – JEP 345
  • Потоковая передача событий JFR – JEP 349
  • Буферы байтов с отображением в постоянную память – JEP 352
  • ZGC на macOS – JEP 364
  • ZGC на Windows – JEP 365
  • API доступа к внешней памяти (Инкубатор) – JEP 370

Настройка установки Java 14 на Mac OS

  • Для начала работы с Java 14 загрузите JDK отсюда: here.
  • Скопируйте и распакуйте tar-файл в /Library/Java/JavaVirtualMachines, как показано ниже:
$ cd /Library/Java/JavaVirtualMachines

$ sudo cp ~/Downloads/openjdk-14_osx-x64_bin.tar.gz /Library/Java/JavaVirtualMachines

$ sudo tar xzf openjdk-14_osx-x64_bin.tar.gz

$ sudo rm openjdk-14_osx-x64_bin.tar.gz

После этого откройте bash_profile с помощью любого текстового редактора. Я использую vim ~/.bash_profile. Установите путь к Java 14 в JAVA_HOME, сохраните изменения и выполните source ~/.bash_profile, чтобы отразить изменения.

export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-14.jdk/Contents/Home

Теперь вы готовы компилировать и запускать программы на Java 14. Мы будем использовать JShell, интерактивное средство командной строки REPL для быстрого тестирования новых функций Java 14.

Важно отметить, что многие функции, выпущенные в Java 14, находятся в режиме предварительного просмотра. Это означает, что хотя они полностью работают сейчас, в будущем они могут быть изменены. Некоторые из них могут стать стандартом или просто быть удалены в следующих циклах релиза. Чтобы протестировать функции предварительного просмотра, необходимо явно установить --enable-preview при запуске JShell или Java-программы, как показано ниже:

jshell --enable-preview

javac --release 14 --enable-preview Author.java

В следующих разделах обсудим некоторые возможности языка и JVM.

Рекомендуемая литература: Установка Java 14 на Linux

1. Выражения переключения

Переключение выражений после оставания функцией предварительного просмотра в последних двух выпусках – Java 12 и Java 13, наконец, приобрели постоянный статус в Java 14.

  • Java 12 представила синтаксис лямбда-выражений для выражений выбора, позволяя использовать несколько меток case для сопоставления с образцом, а также предотвращая проваливание, которое приводит к громоздкому коду. Она также обеспечивала исчерпывающие случаи, при которых возникала ошибка компиляции, если все входные случаи не были рассмотрены.
  • Java 13, второй вариант предварительного просмотра, представил операторы yield вместо break для возвращения значений из выражения.

Java 14 наконец, сделала эти функции стандартными теперь.

String result = switch (day) {
            case "M", "W", "F" -> "MWF";
            case "T", "TH", "S" -> "TTS";
            default -> {
                if(day.isEmpty())
                    yield "Please insert a valid day.";
                else
                    yield "Looks like a Sunday.";
            }

        };
System.out.println(result);
Java 14 Switch Expressions

Примечание: Ключевое слово “yield” не является новым в Java. Оно просто используется в выражениях выбора.

2. Сопоставление с образцом для instanceof (Предварительный просмотр)

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

Java 14 избавляется от этой громоздкости, делая условное извлечение гораздо более кратким.

До Java 14:

if (obj instanceof Journaldev) {
  Journaldev jd = (Journaldev) obj;
  System.out.println(jd.getAuthor());
}

С Java 14 и далее:

if (obj instanceof Journaldev jd) {
  System.out.println(jd.getAuthor());
}

В вышеуказанном коде экземпляр jd будет назначен только в том случае, если obj имеет тип Journaldev. Область видимости переменной ограничена только условным блоком.

3. Полезные исключения NullPointerException

Исключения Null Pointer – кошмар для любого разработчика. Ранее, до Java 13, отлаживание бесчисленных NPE было затруднительным. Разработчики вынуждены были прибегать к другим отладочным инструментам или вручную определять переменную/метод, который был равен null, поскольку стек вызовов показывал только номер строки.

До Java 14:

String name = jd.getBlog().getAuthor()

//Стек вызовов
Exception in thread "main" java.lang.NullPointerException
    at NullPointerExample.main(NullPointerExample.java:5)

Java 14 ввела новую функцию JVM, которая предоставляет лучшие исследования с более подробным стеком вызовов, как показано ниже:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Blog.getAuthor()" because the return value of "Journaldev.getBlog()" is null
    at NullPointerExample.main(NullPointerExample.java:4)

Примечание: Указанная выше функция не является функцией языка. Это улучшение в среде выполнения.

4. Записи (Предварительный просмотр)

A record is a data class that stores pure data. The idea behind introducing records is to quickly create simple and concise classes devoid of boilerplate code.

Обычно класс в Java требует реализации методов equals(), hashCode(), геттеров и сеттеров. Хотя некоторые среды разработки поддерживают автоматическую генерацию таких классов, код по-прежнему громоздкий. С помощью record вам просто нужно определить класс следующим образом.

record Author(){}
//или
record Author (String name, String topic) {}

Компилятор Java автоматически создает конструктор, закрытые конечные поля, методы доступа, equals/hashCode и toString. Автоматически сгенерированные методы getter для указанного класса: name() и topic().

Чтобы просмотреть сгенерированный код, используйте javap Author после компиляции программы с помощью javac. Ниже приведен сгенерированный класс для record Author (String name, String topic) {}:

Javap Records Java 14

Семантика записей аналогична Классам данных в Kotlin

Кроме того, мы можем добавить дополнительные поля, методы и конструктор к записи следующим образом:

record Author (int id, String name, String topic) {
    static int followers;

    public static String followerCount() {
        return "Followers are "+ followers;
    }

    public String description(){
        return "Author "+ name + " writes on "+ topic;
    }

    public Author{
    if (id < 0) {
        throw new IllegalArgumentException( "id must be greater than 0.");
     }
   }
}

Дополнительный конструктор, определенный внутри записи, называется Компактный конструктор. Он не содержит параметров и является только расширением канонического конструктора.

A compact constructor wouldn’t be generated as a separate constructor by the compiler. Instead, it is used for validation cases and would be invoked at the start of the main constructor.

Несколько важных моментов о Записях:

  • A record can neither extend a class nor it can be extended by another class. It’s a final class.
  • Записи не могут быть абстрактными
  • Записи не могут расширять другой класс и не могут определять поля экземпляра внутри тела. Поля экземпляра должны быть определены только в описании состояния
  • Объявленные поля являются закрытыми и конечными
  • Тело записи позволяет статические поля и методы

Рекомендуемая литература: Записи Java

4.1) Значения внутри полей ссылок записи могут быть изменены

Важно отметить, что для определенных полей, которые являются объектами, только ссылка неизменна. Основные значения могут быть изменены. Ниже приведен пример записи, в которой изменяется ArrayList. Как видно, значение изменяется при изменении ArrayList.

Java 14 Records Mutable Values For References

4.2) Записи могут реализовывать интерфейсы

В следующем коде показан пример реализации интерфейса с использованием записей:

record Author(String name, String topic) implements Information {
  public String getFullName() {
    return "Author "+ name + " writes on " + topic;
  }
}

interface Information {
  String getFullName();
}

Вот результат выполнения вышеуказанного кода в JShell:

Java 14 Records With Interface

4.3) Записи поддерживают несколько конструкторов

Записи позволяют объявлять несколько конструкторов с параметрами или без, как показано ниже:

record Author(String name, String topic) {
  public Author() {

    this("NA", "NA");
  }

  public Author(String name) {

    this(name, "NA");
  }
}

4.4) Записи позволяют изменять методы доступа

Хотя записи автоматически создают открытые методы доступа для полей, определенных в описании состояния, они также позволяют вам переопределять эти методы в теле, как показано ниже:

record Author(String name, String topic) {
  public String name() {
        return "This article was written by " + this.name;
    }
}

4.5) Проверка записи и ее компонентов во время выполнения

Записи предоставляют нам методы isRecord() и getRecordComponents() для проверки, является ли класс записью, а также для просмотра его полей и типов. Ниже показано, как это делается:

Java 14 Records Runtime Check

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

5. Текстовые блоки (Предварительная версия)

Блоки текста были представлены как функция предварительного просмотра в Java 13 с целью облегчения создания многострочных строковых литералов. Они полезны при создании HTML, JSON или SQL-строк запросов.

В Java 14 блоки текста все еще находятся в режиме предварительного просмотра с некоторыми новыми дополнениями. Теперь мы можем использовать:

  • Обратный слеш для отображения красивых блоков многострочного текста.
  • \s используется для учета конечных пробелов, которые по умолчанию игнорируются компилятором. Он сохраняет все пробелы, присутствующие перед ним.
String text = """
                Did you know \
                Java 14 \
                has the most features among\
                all non-LTS versions so far\
                """;

String text2 = """
                line1
                line2 \s
                line3
                """;


String text3 = "line1\nline2 \nline3\n"

// текст2 и текст3 равны.

Ссылки: OpenJDK 14

Source:
https://www.digitalocean.com/community/tutorials/java-14-features