Исчерпывающий switch без default
Компилятор проверяет, что все sealed-подтипы охвачены — default не требуется.
Сравнение кода
✕ Java 8
// Must add default even though
// all cases are covered
double area(Shape s) {
if (s instanceof Circle c)
return Math.PI * c.r() * c.r();
else if (s instanceof Rect r)
return r.w() * r.h();
else throw new IAE();
}
✓ Java 21+
// sealed Shape permits Circle, Rect
double area(Shape s) {
return switch (s) {
case Circle c ->
Math.PI * c.r() * c.r();
case Rect r ->
r.w() * r.h();
}; // no default needed!
}
Заметили проблему в этом коде? Сообщите нам.
Почему современный подход лучше
Безопасность на этапе компиляции
Добавьте новый подтип — компилятор покажет каждое место, которое нужно обновить.
Нет мёртвого кода
Никакой недостижимой ветки default, скрывающей ошибки.
Алгебраические типы
sealed + records + исчерпывающий switch = настоящие ADT в Java.
Старый подход
Обязательная ветка default
Современный подход
Исчерпываемость sealed
Начиная с JDK
21
Сложность
Средний
Поддержка JDK
Исчерпывающий switch без default
Доступно
Доступно в JDK 21 LTS (сент. 2023)
Как это работает
При switch по sealed-типу компилятор знает все возможные подтипы и проверяет, что каждый случай обработан. Если добавить новый подтип, компилятор укажет на каждый switch, который стал неполным.
Связанная документация
Доказательство