Appearance
Lesson 06 · Sealed Types
Objectives
After this lesson you will be able to:
- Declare
sealedclasses and interfaces with apermitsclause. - Apply the rule that each permitted subtype is
final,sealed, ornon-sealed. - State the accessibility / location / direct-extension constraints on permitted subtypes.
- Combine sealed hierarchies with records for exhaustive
switch(algebraic data types).
sealed and permits
A sealed class or interface restricts which types may extend or implement it, making the hierarchy closed and fully known to the compiler.
java
sealed interface Shape permits Circle, Square { }
record Circle(double r) implements Shape { } // final (records are final)
final class Square implements Shape {
final double side;
Square(double side) { this.side = side; }
}Every permitted subtype must itself choose one of:
final— no further subclassing (records are automatically final),sealed— continues the closed hierarchy with its ownpermits,non-sealed— re-opens that branch to any subclass.
java
sealed class Vehicle permits Car, Truck { }
final class Car extends Vehicle { }
non-sealed class Truck extends Vehicle { } // anyone may extend Truck
class Pickup extends Truck { } // legal — Truck re-opened the branchA sealed type may be abstract (a common base with abstract methods), and a sealed interface can permit both classes and other interfaces.
Rules for permitted subtypes
A permitted subtype must satisfy all of:
| Rule | Why |
|---|---|
be one of final / sealed / non-sealed | keeps the hierarchy's closedness explicit |
| directly extend/implement the sealed type | permits lists direct subtypes only |
| be accessible to the sealed type | the compiler must see it to check exhaustiveness |
| live in the same module (named) or same package (unnamed module) | locality of the closed set |
Exam trap
A permitted subtype that is none of final/sealed/non-sealed does not compile. The permits clause may be omitted when all subtypes are declared in the same source file (the compiler infers it). A type listed in permits that doesn't actually extend the sealed type is a compile error.
Exhaustive switch with sealed types
Because the compiler knows the complete set of subtypes, a switch over a sealed type can be exhaustive without a default — and it errors if you miss a case or add a new subtype later.
java
double area(Shape s) {
return switch (s) {
case Circle c -> Math.PI * c.r() * c.r();
case Square sq -> sq.side() * sq.side();
// no default needed — Circle and Square exhaust Shape
};
}SDET note
Sealed + records + exhaustive switch turn "did I handle every case?" into a compile-time check. Add a new permitted subtype and every non-exhaustive switch fails to compile — the compiler becomes a regression test for missing branches.
Algebraic data types (sealed + records + patterns)
The killer combination: a sealed interface with record implementations models a closed set of shapes of data, and a pattern switch deconstructs them — recursively, with no default.
java
sealed interface Expr permits Num, Add { }
record Num(int value) implements Expr { }
record Add(Expr left, Expr right) implements Expr { }
int eval(Expr e) {
return switch (e) {
case Num(int v) -> v;
case Add(Expr l, Expr r) -> eval(l) + eval(r);
};
}Beyond the exam
At runtime you can inspect a sealed type reflectively: Shape.class.isSealed() and getPermittedSubclasses(). This is reflection territory (Module 11), not a 1Z0-830 objective — but it confirms the closed set the compiler enforces.
Key Takeaways
sealed … permits A, Bcloses a class or interface to a known set;permitsmay be omitted when subtypes share the file. A sealed type may beabstract.- Each permitted subtype must be
final,sealed, ornon-sealed, directly extend the sealed type, be accessible, and live in the same module/package. non-sealedre-opens a branch to arbitrary subclasses.- A
switchover a sealed type can be exhaustive withoutdefault; missing a subtype is a compile error. - Sealed interfaces + records + pattern
switchmodel algebraic data types with compiler-checked exhaustiveness.
Lesson Quiz
A permitted subtype of a sealed type must be...
When can the permits clause be omitted?
Why can this switch omit default?
sealed interface S permits A, B {} // switch over an S handling case A, case BWhat does non-sealed mean?
Which is NOT a requirement for a permitted subtype?
Can a sealed class also be abstract?
Given non-sealed class Truck extends Vehicle {}, is class Pickup extends Truck {} legal?
Next: Nested & Inner Classes. Run the matching code in labs/src/main/java/com/jse21/m03_oop/.