Understand what sealed classes express in Java design and when a closed hierarchy is more honest than open inheritance.
Sealed class: A class or interface that explicitly restricts which types may extend or implement it.
Sealed classes matter because they let the type system express a rule that older Java often left in comments: only these variants are valid.
1public sealed interface PaymentResult
2 permits PaymentResult.Success, PaymentResult.Failure {
3
4 record Success(String confirmationId) implements PaymentResult {}
5 record Failure(String reason) implements PaymentResult {}
6}
That is stronger than documentation alone. It tells both the compiler and the reader that the set of possibilities is closed.
Closed hierarchies are common in real systems:
Before sealed classes, Java often modeled these with:
Sealed types give a better middle ground.
They are strongest when the domain genuinely has a known set of variants. Examples include:
In those cases, open extension would be a bug, not a feature.
Avoid sealed hierarchies when a model is expected to be extended by:
Sealing a hierarchy that should stay open only pushes extensibility problems somewhere else.
Sealed classes influence:
They do not replace those patterns completely, but they often make the domain boundary clearer and the implementation safer.
Use sealed classes when the domain says “these are the only legal variants.” If the hierarchy is meant to be extensible by others, do not seal it just because the feature exists.