Sealed classes & interfaces (Java 17)
sealed permits restricts the hierarchy — enabling exhaustive switch without default.
Closing the inheritance door — selectively
A sealed class (or interface) declares the exact set of classes permitted to extend it:
public sealed class Shape
permits Circle, Rectangle, Triangle { }
public final class Circle extends Shape {
double radius;
}
public non-sealed class Rectangle extends Shape { // anyone can extend Rectangle
int width, height;
}
public sealed class Triangle extends Shape
permits EquilateralTriangle, RightTriangle { } // Triangle is itself sealed
Every class in the permits list must directly extend the sealed class and must be declared as one of:
- final — no further extension allowed.
- sealed — extends the hierarchy with its own permits list.
- non-sealed — reopens the hierarchy; anyone can extend it.
Exhaustive switch — the payoff
Because the compiler knows every possible subtype, a switch expression can be exhaustive without a default branch:
String desc = switch (shape) {
case Circle c -> "circle r=" + c.radius;
case Rectangle r -> "rect " + r.width + "x" + r.height;
case Triangle t -> "triangle";
// no default needed — all permitted subtypes covered
};
This enables the pattern switch (Java 21 feature preview in 17) to verify completeness at compile time — catching missed subtypes rather than silently falling through to an unexpected branch at runtime.