← Назад к списку
ТехническаяJava и KotlinMiddle

Расскажите про records, sealed-классы и pattern matching. Какие задачи они решают вместе?

Короткий ответ

  • record — неизменяемый носитель данных с готовыми equals/hashCode/toString
  • Компоненты record финальны, наследоваться от классов нельзя
  • sealed ограничивает список наследников через permits
  • switch с pattern matching разбирает типы и деконструирует record
  • sealed + switch = исчерпывающая проверка без default
  • Вместе это алгебраические типы данных для моделирования домена

Records и sealed-иерархии со switch pattern matching дают компактное и типобезопасное моделирование доменных состояний.

Как сказать вслух

пример ответа

Record — это класс для данных: я перечисляю компоненты, а конструктор, геттеры, equals, hashCode и toString генерируются сами, и объект неизменяемый. Sealed-класс или интерфейс жёстко ограничивает, кто может его наследовать. А pattern matching в switch позволяет разобрать объект по типу и сразу вытащить поля. Вместе это удобно для моделирования состояний: компилятор сам проверит, что я обработал все варианты, и сломает сборку, если добавится новый.

Подробный ответ

Основной ответ

record (с Java 16) — финальный класс с финальными компонентами: канонический конструктор, методы доступа, equals/hashCode/toString генерируются; инварианты проверяют в компактном конструкторе. Это убирает шаблонный код DTO и value-объектов. sealed (с Java 17) ограничивает наследников списком permits; наследник обязан быть final, sealed или non-sealed. Pattern matching: instanceof с паттерном типа, switch по типам (Java 21) и record patterns — деконструкция вложенных структур: case Circle(Point(var x, var y), var r). Ключевая синергия: switch по sealed-иерархии проверяется на исчерпываемость — забытый вариант даёт ошибку компиляции, default не нужен и даже вреден. Это приближает Java к алгебраическим типам данных: Result = Ok | Error, события, состояния заказа — вместо enum с полями-«на все случаи» или иерархий с visitor.

Ключевые моменты

  • record. Неизменяемый носитель данных; валидация — в компактном конструкторе; изменение — через производящие методы (with-подход).
  • sealed. Закрытая иерархия: компилятор знает всех наследников, что и делает возможной исчерпывающую проверку.
  • Record patterns. Деконструкция в switch/instanceof, включая вложенные records и var для компонентов.
  • Исчерпываемость. Без default добавление нового наследника ломает компиляцию всех switch — ошибки находят на сборке.

Практический контекст

В проде records используют для DTO, событий, ключей кэшей, результатов методов (вместо null или исключений — sealed Result). Интервьюер проверяет знание современной Java: когда record нельзя (нужна изменяемость, наследование, JPA-сущности — прокси и ленивость с records не дружат) и зачем не ставить default в switch по sealed. Хорошо упомянуть, что record может реализовывать интерфейсы и иметь статические фабрики.

Частые ошибки

  • Используют record для JPA-сущностей, где нужны прокси и изменяемое состояние
  • Добавляют default в switch по sealed-иерархии, теряя проверку исчерпываемости
  • Считают record полностью неизменяемым, забывая про изменяемое содержимое компонентов-коллекций

ИП Кочкин Алексей Сергеевич · ИНН 390509026279 · ОГРНИП 325390000030973 · jiniys2005@yandex.ru