library
intermediateSealed Classes & Interfaces (Java 17)
Restrict which classes can extend a type — enabling exhaustive pattern matching and controlled hierarchies.
A sealed type names exactly which types may extend it.
Sealed class = an invitation-only club. Only approved members (permitted subtypes) can join. Everyone else is turned away at the door.
Key Concepts
1
sealed interface Shape permits Circle, Rectangle, Triangle { }2
record Circle(double r) implements Shape { }
record Rectangle(double w, double h) implements Shape { }
record Triangle(double b, double h) implements Shape { }3
Each permitted subtype must declare its own intent.
final no further extension
sealed extension restricted again
non-sealed deliberately reopened4
Records are implicitly final, which is why they pair with sealed types so neatly.
5
The payoff is exhaustiveness.
double area(Shape s) {
return switch (s) {
case Circle c -> Math.PI * c.r() * c.r();
case Rectangle r -> r.w() * r.h();
case Triangle t -> t.b() * t.h() / 2;
}; // no default needed
}6
The compiler knows the list is complete, so it accepts the switch without a default. And if someone adds
a fourth shape, this stops compiling — which is exactly what you want, because it points at every place
that needs the new case.
default
7
A default branch would have hidden that. It would compile, run, and silently return the wrong answer.
default
8
Where the subtypes must live. The same module, or the same package if there is no module. That is what
lets the compiler trust the list.
9
permits can be omitted when the subtypes are in the same file:
permits
10
sealed interface Shape { }
record Circle(double r) implements Shape { }11
What it gives you beyond switches.
a hierarchy you can reason about completely
an API that states which extensions are supported
sensitive interfaces that cannot be implemented by callers12
This is Java's version of an algebraic data type — a fixed set of shapes, each with its own data, handled
exhaustively. Before sealed types you wrote the visitor pattern to get the same guarantee, with far more
code.
13
What the interviewer is probing.1. "What problem do sealed types solve?" Probing: exhaustiveness. Stalls: "They stop people
extending things." Moves up: the compiler knows every subtype, so a switch can be exhaustive
without a default — and adding a subtype then breaks the build at every place that must change.
14
2. "Why is omitting default in an exhaustive switch better than including it?" Probing: the
real benefit. Stalls: "It is shorter." Moves up: a default silently absorbs a new subtype and
returns a wrong answer; without it the compiler points at every site that needs updating.
15
3. "What must a permitted subclass declare?" Probing: the rule. Stalls: "Nothing." *Moves
up:* final, sealed or non-sealed — so the hierarchy stays closed or is reopened deliberately.
16
4. "How do sealed interfaces relate to the visitor pattern?" Probing: whether you can place it
historically. Stalls: "They are unrelated." Moves up: they give the same exhaustiveness
guarantee that visitor was invented to provide, with far less code.