Общее введение в наиболее эффективные обновления Java 14 и Java 15

В настоящее время Java является одним из самых распространенных языков программирования во всем мире с его Java SE 8, выпущенным 18 марта 2014 года, который составляет около 60% использования в основных приложениях.

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

Давайте сделаем обзор основного JEP (Java Enhancement Proposal) для каждого выпуска.

Java 14: сопоставление с образцом для instanceof (JEP 305), полезных исключений NullPointerExceptions (JEP 358), записей (JEP 359), выражений переключения (JEP 361 ), текстовые блоки ( JEP 368 )

Java 15: запечатанные классы или интерфейсы (JEP 360)

Java 14

Сопоставление с образцом для instanceof

Каждый Java-программист должен знать старый синтаксис, используемый для определения блока instanceof. Он предусматривал три основных шага: тест, объявление новой переменной и преобразование (преобразование obj в String).

if (obj instanceof String) {
    String s = (String) obj;
    // use s
}

Оператор istanceof теперь расширен, чтобы принимать образец проверки типа, а не только тип. В приведенном ниже примере YourClass y - это тестовый образец типа.

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

Такой синтаксис также упрощает реализацию методов. Внимательно изучите методы equals () и multiply () в приведенном выше фрагменте.

Полезные исключения NullPointerExceptions

JVM выдает исключение NullPointerException (NPE), когда программа пытается разыменовать пустую ссылку. По сути, это усовершенствование направлено на повышение удобства использования NPE, сгенерированного JVM, путем точного описания того, какая переменная имеет значение NULL. Теперь представьте, что у нас есть следующее выражение присваивания:

a.i = 99

… И считайте, что a имеет значение NULL. Выполнение заставит JVM распечатать метод, имя файла и номер строки, вызвавшие NPE.

Exception in thread "main" java.lang.NullPointerException
    at Program.main(Program.java:5)

С выпуском Java 14 и JEP 358 сообщение будет:

Exception in thread "main" java.lang.NullPointerException: 
        Cannot assign field "i" because "a" is null
    at Program.main(Program.java:5)

В более сложном заявлении:

a.b.c.i = 99
Exception in thread "main" java.lang.NullPointerException: 
        Cannot read field "c" because "a.b" is null
    at Program.main(Program.java:5)

Записи

Все знают, что Java действительно слишком многословна. На мой взгляд, записи - одно из лучших улучшений, когда-либо существовавших, специально для классов, которые являются просто агрегаторами данных или носителями, получающими исключительный уровень краткости, представляемыми только именем и состоянием. Государство объявляет компоненты записи.

Запись неявно определяет:

  • Закрытое финальное поле для каждого компонента описания состояния
  • Открытый метод доступа для чтения для каждого компонента описания состояния.
  • Открытый конструктор с той же подписью описания состояния
  • Реализация методов equals (), hashCode () и toString ()

Какие ограничения на записи?

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

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

Переключить выражения

Как правило, блок переключения позволяет приложению иметь несколько возможных путей выполнения в зависимости от результата выражения во время выполнения.

В Java 14 выражения switch были расширены, в них появилось много новых интересных функций.

Давайте запишем только старый метод, используемый для определения выражений блока:

switch(expression) {
  case a:
    // code block
    break;
  case b:
    // code block
    break;
  default:
    // code block
}

В JEP 361 введена новая форма метки переключателя: «case a -› ». Это означает, что только код справа от метки должен выполняться, если метка совпадает.

Новая версия предыдущего фрагмента кода становится

switch(expression) {
  case a -> // code
  case b -> // code
  default -> // code
}

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

T result = switch(expression) {
  case label1 -> expression1;
  case label2 -> expression2;
  default -> expression3;
}

Получение значения

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

T result = switch(expr) {
  case label1 -> expression1;
  case label2 -> expression2;
  default -> {
    expression3;
    expression4;
    yield result;
}

Очень важно помнить о следующем пункте:

Два оператора, break (с меткой или без нее) и yield, упрощают устранение неоднозначности между операторами switch и выражениями switch: оператор switch, но не выражение switch, может быть целью оператора break; и выражение switch, но не выражение switch, может быть целью оператора yield.

Это означает, что ключевое слово yield используется только для возврата значения из полного кода блока; результат, который нужно присвоить переменной.

Итак, в конце я хочу сообщить еще об одном примере нового популярного оператора switch, используемого в качестве выражения внутри syso call:

static void isEven(int k) {
    int e = k % 2;
    System.out.println(
        switch (e) {
            case  0 -> true;
            case  1 -> false;
            default -> "WTF";
        }
    );
}

Текстовые блоки

Добро пожаловать, текстовые блоки! Отныне разработчики могут определять строки, которые охватывают несколько строк исходного кода (например, HTML, SQL-запрос), избегая управляющих последовательностей, улучшающих читаемость, например, в Python. Примером может быть следующее:

String query = """
               SELECT `PERSON_ID`, `NAME` FROM `PERSONS`
               WHERE `AGE` > 35
               ORDER BY `PERSON_ID`, `NAME`;
               """;

Java 15

Запечатанные классы или интерфейсы

Запечатанные классы (или интерфейсы) - это интересная функция, представленная в Java 15 вместе с JEP 360. Очевидно, что цель наследования состоит не только в повторном использовании кода, но даже в моделировании различных возможностей, существующих в домене.

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

В качестве примера мы можем решить определить абстрактный класс Animal и смоделировать домен только с помощью Reptiles и Amphibians, таких как фрагмент кода ниже .

Надеюсь, вам понравилась эта статья!

Спасибо ❤