Поиск по сайту:

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


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

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

Вот список функций Java 14:

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

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

  • Чтобы начать работу с Java 14, загрузите JDK отсюда.
  • Скопируйте и извлеките файл 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. Установите путь Java14 к 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);

Примечание. 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

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

До Java 14:

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

//Stacktrace
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. Записи (предварительная версия)

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

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

record Author(){}
//or
record Author (String name, String topic) {}

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

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

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

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

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.");
     }
   }
}

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

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

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

  • Запись не может ни расширять класс, ни расширяться другим классом. Это последний урок.
  • Записи не могут быть абстрактными
  • Записи не могут расширять какой-либо другой класс и не могут определять поля экземпляра внутри тела. Поля экземпляра должны быть определены только в описании состояния.
  • Объявленные поля являются закрытыми и окончательными.
  • В теле записи можно использовать статические поля и методы.

Рекомендуемая литература: отчеты Java

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

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

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

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

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

interface Information {
  String getFullName();
}

Вот вывод приведенного выше кода в действии в JShell:

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(), чтобы проверить, является ли класс записью, а также изучить его поля и типы. На следующем рисунке показано, как это делается:

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

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"

//text2 and text3 are equal.

Ссылки: OpenJDK 14