«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.