Unravel โบ Java concepts โบ OOP and types
Sealed classes and interfaces
sealed restricts who may extend or implement a type: sealed interface Shape permits Circle, Square.
Learn these first
At a glance
A closed guest list.
- 1The permits clause names the allowed subclasses (they can be omitted if all are in the same file)Each permitted subtype must be final, sealed or non-sealed.
- 2Records and enums are implicitly final, so they are ideal permitted subtypes: record Circle(double r) implements Shape {}
- 3A switch over a sealed type needs no default: the compiler checks every permitted case is handled and errors when a new subtype is added and a switch forgets it
- Sealed types model "one of these exactly": a result that is Success or Failure, an event that is Created, Updated or Deleted
- The set is closed at compile time, so unlike an open interface a library cannot be extended by outside code
- The permitted subclasses are stored in the PermittedSubclasses attribute of the class file; the JVM refuses to load a class that extends a sealed type without being listed there
public sealed interface Shape permits Circle, Square {}record Circle(double r) implements Shape {}record Square(double side) implements Shape {}class Areas { static double area(Shape s) { return switch (s) { case Circle c -> Math.PI * c.r() * c.r(); case Square q -> q.side() * q.side(); }; }}Read the full explanation (about 1 min)
sealed restricts who may extend or implement a type: sealed interface Shape permits Circle, Square. The compiler then knows every possible subtype.
A mental model
A closed guest list. Nobody turns up who is not on it, so the host can prepare a place for every guest and know that nobody is missing.
How it works
The permits clause names the allowed subclasses (they can be omitted if all are in the same file). Each permitted subtype must be final, sealed or non-sealed.
Records and enums are implicitly final, so they are ideal permitted subtypes: record Circle(double r) implements Shape {}.
A switch over a sealed type needs no default: the compiler checks every permitted case is handled and errors when a new subtype is added and a switch forgets it.
Going deeper
Sealed types model "one of these exactly": a result that is Success or Failure, an event that is Created, Updated or Deleted. This is the Java version of algebraic data types.
The set is closed at compile time, so unlike an open interface a library cannot be extended by outside code. That is the trade: safety for you, less freedom for others.
Under the hood
The permitted subclasses are stored in the PermittedSubclasses attribute of the class file; the JVM refuses to load a class that extends a sealed type without being listed there.
Common mistakes
- Forgetting that every permitted subclass must say
final,sealedornon-sealed. - Keeping a
defaultbranch in a switch, which hides the missing-case compile error. - Sealing a type in a library that others are expected to extend.
How Unravel recognises it
When you paste code, Unravel looks for these signs of sealed classes and interfaces. Spotting them yourself is a good habit when you read unfamiliar code:
- Language constructs:
permits
Part of a learning path
- Modern Java syntax ยท previous: Varargs ยท next: Pattern matching with instanceof
Related concepts
Frequently asked questions
What is Sealed classes and interfaces?
sealed restricts who may extend or implement a type: sealed interface Shape permits Circle, Square. The compiler then knows every possible subtype.
What are the most common mistakes with Sealed classes and interfaces?
Forgetting that every permitted subclass must say final, sealed or non-sealed. Keeping a default branch in a switch, which hides the missing-case compile error. Sealing a type in a library that others are expected to extend.
How can I see Sealed classes and interfaces in real code?
Paste your own Java into Unravel and it will point out where sealed classes and interfaces appears, explain how it works at the detail level you choose, and draw the flow of the code around it.