ПрограммированиеBackend разработчик

Что такое pattern matching в Java, на какой стадии его внедрение, для чего он используется и какие нюансы надо знать? Приведите пример.

Проходите собеседования с ИИ помощником Hintsage

Ответ.

История вопроса

Pattern matching — приём, заимствованный из функциональных и скриптовых языков, позволяющий проверять тип и извлекать данные за один шаг. В Java развитие pattern matching началось c Java 14 (preview feature), улучшилось в Java 16–17, а в последних релизах расширяется на switch.

Проблема

Классический способ проверки типа и приведения выглядел громоздко:

if (obj instanceof String) { String s = (String) obj; ... }

Появлялись лишние переменные, большое количество шаблонного кода и риск ошибок приведения типов.

Решение

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

if (obj instanceof String s) { System.out.println(s.length()); }

Аналогичные паттерны теперь появляются в конструкции switch, что делает код лаконичнее и менее подверженным ошибкам.

Ключевые особенности:

  • Лаконичная и безопасная работа с типами.
  • Уменьшение количества ошибок при кастах.
  • Простота поддержки кода и расширения на новые типы.

Вопросы с подвохом.

Можно ли использовать pattern matching для кастомных (пользовательских) классов или только для стандартных типов?

Можно использовать для любых классов. Pattern Matching работает для всех классов, с которыми можно применять instanceof.

Будет ли переменная паттерна доступна вне блока if/switch?

Нет, объявленная внутри pattern matching переменная видна только в пределах того блока, где создана (например, внутри if или case switch).

Пример кода:

if (obj instanceof Integer i) { // i видна только в этом блоке System.out.println(i + 10); } // Здесь i недоступна

Можно ли использовать pattern matching с дженериками?

Да, вот так:

Object list = List.of("a", "b"); if (list instanceof List<?> l) { System.out.println(l.size()); }

Но работа с raw-типами и приведение к параметризованным типам всё ещё ограничена из-за type erasure.

Типовые ошибки и анти-паттерны

  • Предположение, что pattern matching автоматически обрабатывает null: если объект равен null, условие не выполнится (instanceof с null всегда false).
  • Использование pattern matching там, где достаточно метода getClass().
  • Слишком частое применение pattern matching может ухудшить архитектуру, если намерения неочевидны.

Пример из жизни

Негативный кейс

Команда внедрила pattern matching во всех случаях, включая внутренние DTO, сервисные классы и случаи, где достаточно было полиморфизма. Код стал слишком завязан на instanceof, роль иерархий классов размыта.

Плюсы:

  • Быстрое внедрение.
  • Лаконичный стиль.

Минусы:

  • Архитектурные просчёты.
  • Меньшая читаемость.

Позитивный кейс

В проекте pattern matching применяли только для общих интерфейсов, вспомогательных утилит и обработки коллекций неизвестного типа. Архитектура ООП сохранена, использование паттерна только там, где без него не обойтись.

Плюсы:

  • Читаемый код.
  • Поддержка архитектуры.

Минусы:

  • Требует внимательного проектирования и знания версии JDK.