«1. Обзор

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

Таким образом, JEP 305 направлен на то, чтобы сделать условное извлечение компонентов из объектов намного более простым, кратким, читабельным и безопасным.

2. Традиционный оператор instanceOf

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

Давайте представим, что мы хотим проверить тип в простой иерархии объектов животных:

if (animal instanceof Cat) {
    Cat cat = (Cat) animal;
    cat.meow();
   // other cat operations
} else if (animal instanceof Dog) {
    Dog dog = (Dog) animal;
    dog.woof();
    // other dog operations
}

// More conditional statements for different animals

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

Несмотря на то, что этот подход работает, он имеет несколько недостатков:

    Утомительно писать код такого типа, где нам нужно тестировать тип и выполнять приведение типов для каждого условного блока. Мы повторяем имя типа три раза для каждого блока if. Читабельность плохая, поскольку в коде преобладают приведение типов и извлечение переменных. Повторное объявление имени типа означает большую вероятность появления ошибки. Это может привести к неожиданной ошибке во время выполнения. Проблема усугубляется каждый раз, когда мы добавляем новое животное

В следующем разделе мы рассмотрим, какие улучшения предоставляет Java 14 для устранения этих недостатков.

3. Усовершенствованный instanceOf в Java 14

Java 14 через JEP 305 предоставляет улучшенную версию оператора instanceof, который одновременно проверяет параметр и присваивает его переменной привязки соответствующего типа.

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

if (animal instanceof Cat cat) {
    cat.meow();
} else if(animal instanceof Dog dog) {
    dog.woof();
}

Давайте разберемся, что здесь происходит. В первом блоке if мы сопоставляем животное с образцом типа Кошка кошка. Во-первых, мы проверяем переменную animal, чтобы увидеть, является ли она экземпляром Cat. Если да, то он будет приведен к нашему типу Cat, и, наконец, мы присвоим результат cat.

Важно отметить, что имя переменной cat не является существующей переменной, а является объявлением переменной шаблона.

Мы также должны упомянуть, что переменные cat и dog находятся в области видимости и назначаются только тогда, когда соответствующие выражения сопоставления с образцом возвращают значение true. Следовательно, если мы попытаемся использовать любую переменную в другом месте, код будет генерировать ошибки компилятора.

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

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

4. Заключение

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

Как всегда, полный исходный код статьи доступен на GitHub.