Какое важное изменение для моделирования предметной области появилось при переходе с Java 11 на Java 17?

«Какое важное изменение для моделирования предметной области появилось при переходе с Java 11 на Java 17?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Ключевым нововведением для моделирования предметной области стали sealed classes (запечатанные классы), официально добавленные в Java 17. Они позволяют явно ограничивать иерархию наследования.

Проблема до Java 17: Нельзя было ограничить, какие классы могут расширять базовый класс или интерфейс, что усложняло безопасную работу с типами (например, требовались длинные цепочки instanceof).

Решение с sealed классами:

// Базовый запечатанный класс. Ключевое слово 'permits' указывает допустимых наследников.
public sealed class Shape permits Circle, Rectangle, Triangle {
    // Общие свойства и методы для всех фигур
}

// Наследники должны быть явно объявлены как final, sealed или non-sealed.
public final class Circle extends Shape { /* ... */ }
public final class Rectangle extends Shape { /* ... */ }
public final class Triangle extends Shape { /* ... */ }
// Класс 'Square' не сможет унаследовать Shape, так как не указан в permits.

Преимущества и последствия:

  • Безопасность типов: Компилятор знает все возможные подтипы, что улучшает анализ и позволяет использовать исчерпывающие выражения switch (вместе с switch для типов, preview в Java 17).
  • Четкое проектирование: Явно документирует иерархию типов в коде, заменяя антипаттерны.
  • Требования к наследникам: Каждый разрешенный наследник должен быть объявлен как:
    • final – дальнейшее наследование запрещено.
    • sealed – наследование разрешено, но для нового класса также нужен свой список permits.
    • non-sealed – класс открыт для неограниченного наследования ("снимает печать").