Получить доступ

Какое главное преимущество даёт sealed-иерархия при использовании switch с pattern matching?

MiddleСовременная JavaJava >=21
Ещё спрашивают так:
  • Что дают sealed-типы и почему в паре с pattern matching они меняют стиль кода?
Коротко

Закрытый список наследников делает проверку полноты switch работой компилятора: не нужен default, а новый подтип — ошибка компиляции во всех switch, которые его не обрабатывают. Вместо молчаливого провала в default.

  • Моделирование «суммы типов»: Result = Success | Failure
  • Заменяет Visitor без accept-методов
  • Record-паттерны разбирают компоненты: case Circle(var r) -> ...

А ещё Поведение уходит из иерархии в функции над данными — data-oriented programming

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

В обычной открытой иерархии компилятор не может знать всех наследников, поэтому требует default — и добавление нового подтипа тихо проваливается в эту ветку. Sealed фиксирует список через permits, и тогда switch по типу проверяется на исчерпываемость: забыли вариант — ошибка компиляции, то есть все места, требующие правки, найдены за вас. Это сознательный размен: жертвуем открытостью к расширению (принципом OCP) ради полноты проверки. Правило применимости простое: вариантов конечное число и меняются они редко — sealed уместен; иерархия открыта для сторонних реализаций — нет.

Пример

sealed interface Shape permits Circle, Square {}
record Circle(double r) implements Shape {}
record Square(double side) implements Shape {}

double area(Shape s) {
    return switch (s) {
        case Circle(var r) -> Math.PI * r * r;
        case Square(var a) -> a * a;
    };   // default не нужен
}

Что хотят услышать

  • Исчерпываемость без default.
  • Пример алгебраического типа.
  • Связь с заменой Visitor.

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

  • Добавлять default в исчерпывающий switch по sealed-типу — это возвращает молчаливое поведение при добавлении варианта.
  • Применять sealed к иерархии, которую расширяют потребители библиотеки.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓Компилятор знает полный список наследников и проверяет исчерпываемость switch, поэтому ветка default не нужна
  • ✗Ускоряется диспетчеризация вызовов за счёт отказа от виртуальных методов
  • ✗Наследники автоматически получают реализацию equals и hashCode
  • ✗Все наследники становятся неизменяемыми

Что спросят дальше

  • Почему sealed считают заменой паттерну Visitor?
  • Что должны объявлять сами наследники sealed-типа?
  • Как sealed-типы связаны с record и почему их часто используют вместе?
  • Как в switch с паттернами обрабатывается null?

Разбор темы

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем