Working with Sealed Classes (Java 17+)
1. Declaring Sealed Classes
Example: Sealed hierarchy
public sealed class Shape permits Circle, Square, Triangle {}
public final class Circle extends Shape {}
public final class Square extends Shape {}
public non-sealed class Triangle extends Shape {}
| Modifier | Effect |
|---|---|
sealed | Restricts subclasses to permits list |
final | Subclass cannot be extended |
sealed (subclass) | Continue restricted hierarchy |
non-sealed | Open subclass back up |
2. Using permits Clause
| Rule | Detail |
|---|---|
| Same module/package | Permitted classes must be accessible |
| Direct subtypes only | Listed classes must directly extend/implement |
| Optional | Can omit if all permitted are in same file |
3. Creating Permitted Subclasses
| Subclass Modifier | Required |
|---|---|
final | Closes hierarchy at this leaf |
sealed | Continue with own permits |
non-sealed | Allow unrestricted subclassing |
4. Understanding Sealed Interfaces
Example: Sealed interface
public sealed interface Result<T> permits Success, Failure {}
public record Success<T>(T value) implements Result<T> {}
public record Failure<T>(String error) implements Result<T> {}
| Aspect | Detail |
|---|---|
| Implementors | Restricted via permits |
| Common pattern | Sealed interface + record subtypes (algebraic data types) |
5. Combining Sealed Classes with Pattern Matching
Example: Exhaustive switch
String describe(Result<Integer> r) {
return switch (r) {
case Success<Integer> s -> "OK: " + s.value();
case Failure<Integer> f -> "Error: " + f.error();
}; // no default needed — exhaustive
}
| Benefit | Detail |
|---|---|
| No default | Compiler verifies all cases covered |
| Refactor-safe | Adding new permitted type causes compile error |
6. Understanding Exhaustiveness Checking
| Trigger | Behavior |
|---|---|
| Switch on sealed type | Compiler verifies all permitted subtypes covered |
| Missing case | Compile error |
| Add subtype later | All switches re-checked |
7. Using Sealed Classes for Domain Modeling
| Pattern | Use Case |
|---|---|
| Result/Either | Success vs Failure |
| AST nodes | Expression types |
| State machine | Finite states |
| Event types | Event sourcing |
8. Comparing Sealed Classes vs Final Classes
| Aspect | Sealed | Final |
|---|---|---|
| Subclassing | Allowed (restricted) | None |
| Pattern matching | Exhaustive checks supported | N/A |
| Closed type set | Yes (known at compile) | Single class |