BackendBench
Coffee

Unravel โ€บ Java concepts โ€บ OOP and types

Java language

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

Mental model

A closed guest list.

What happens, in order
  1. 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.
  2. 2Records and enums are implicitly final, so they are ideal permitted subtypes: record Circle(double r) implements Shape {}
  3. 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
Remember
Watch out
Forgetting that every permitted subclass must say final, sealed or non-sealedKeeping a default branch in a switch, which hides the missing-case compile errorSealing a type in a library that others are expected to extend
Example (highlighted lines explain it)
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, 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 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:

Part of a learning path

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.