Sealed classes

Тема дорожной карты · Java

Sealed Classes в Java — языковая функция, финализированная в Java 17, позволяющая классу или интерфейсу явно ограничивать, какие другие классы или интерфейсы могут его расширять или реализовывать, формируя замкнутую, принудительно проверяемую компилятором иерархию подтипов. Объявленные с модификатором sealed и предложением permitssealed interface Shape permits Circle, Rectangle, Triangle — Sealed Classes дают компилятору полное знание обо всех возможных подтипах, обеспечивая исчерпывающие switch-выражения и Pattern Matching без ветви default. Каждый разрешённый подтип должен быть объявлен final (без дальнейшего расширения), sealed (дополнительно ограниченная иерархия) или non-sealed (открыт для произвольного расширения), давая проектировщикам точный контроль над контрактом расширяемости на каждом уровне иерархии типов. Sealed Classes в Java непосредственно сочетаются с Records (которые являются final) для создания алгебраических типов данных, напоминающих иерархии sealed class Haskell или Kotlin — например, sealed interface Result<T> permits Success<T>, Failure, подкреплённый реализациями-записями, предоставляет типобезопасную альтернативу исключениям в функциональных конвейерах с Stream API или Optional. Комбинация Sealed Classes, Pattern Matching и Records — краеугольный камень современных Java-функций, заменяющий сложные паттерны посетителей и цепочки instanceof лаконичной, проверяемой компилятором диспетчеризацией в доменных моделях Spring, событийно-ориентированных архитектурах и JVM-интерпретаторах DSL.

Как это работает

Sealed classes — это Java 17/21 LTS с фичами, меняющими, как пишется код: records (immutable data), sealed-типы (закрытая иерархия), pattern matching для switch (21+), текстовые блоки, var, switch-выражения, records как pattern-deconstructed типы. Virtual threads (21) драматически упрощают concurrent server-код. Reactive-программирование (Project Reactor, RxJava) ещё актуально, но virtual threads сужают его нишу.

Когда применять

Таргет 21 LTS для новых проектов — одни virtual threads стоят апгрейда. Records — для DTO, sealed-типы — для конечных иерархий, pattern matching — при диспетчеризации по типу. Миграция с reactive (Project Reactor) на virtual threads — где читаемость бьёт async-stream-преимущества. GraalVM native image — когда важны быстрый старт + низкая память (CLI-тулзы, serverless).

Типичные ошибки

Ловушки Sealed classes: блокировка на virtual thread внутри synchronized-блока (пиннит carrier — теряет смысл); чрезмерное использование records для mutable-концептов (поля records — final); баги reflection в GraalVM native image (требуют файлы конфигурации); расчёт, что cancellation Reactor идентичен interruption virtual thread (разная семантика).

Связанные понятия

Полезные ресурсы