W3docs

Java Sealed Classes

Restrict which classes can extend or implement a type in Java using sealed classes and the permits clause.

A sealed class or interface restricts who is allowed to extend or implement it to a fixed, named list of subtypes. final says "no one can extend me." sealed says "only these specific classes can." It gives you a closed hierarchy — the compiler knows the entire family up front, which unlocks exhaustive switch and disciplined modeling of "one of N" shapes.

Without sealing, an abstract class Shape is open to the world: anyone with access to the type can write class Banana extends Shape. With sealed, the author of Shape declares exactly which subtypes exist, and adding one requires editing the parent.

The basic syntax

A sealed class lists its permitted subtypes with permits:

public sealed class Shape
    permits Circle, Square, Triangle {
  // common state and behavior
}

Each permitted subtype must itself declare what it does with the seal — one of final, sealed (with its own permits), or non-sealed:

public final     class Circle   extends Shape { /* leaf */ }
public final     class Square   extends Shape { /* leaf */ }
public non-sealed class Triangle extends Shape { /* re-opens the door */ }
  • final — no further subclasses; this is a leaf in the hierarchy.
  • sealed — extends the same model; has its own permits list.
  • non-sealed — opts back out; anyone may now extend Triangle. Useful when you want a closed top-level family with one open branch.

A sealed type with no modifier on a subtype is a compile error — the compiler forces you to choose.

Sealed interfaces

Interfaces follow the same rules and are usually the more natural choice for modeling families of cases:

public sealed interface Result<T>
    permits Success, Failure {}

public record Success<T>(T value) implements Result<T> {}
public record Failure<T>(String message) implements Result<T> {}

Combined with records, you get something close to the "sum type" or "tagged union" from functional languages — a closed list of named alternatives, each with its own data.

Same module, same package (or explicit permits)

The permitted subtypes have to be accessible to the sealed declaration at compile time. The shortest setup is to put the sealed class and its permitted subtypes in the same source file — then you can even omit permits, because the compiler infers it:

public sealed interface Tree {
  record Leaf(int value)               implements Tree {}
  record Node(Tree left, Tree right)   implements Tree {}
}

If they live in separate files, they must be in the same package (or, in a modular project, the same module), and the permits clause is required.

The payoff: exhaustive switch

The compiler knows every possible subtype of a sealed type. That lets switch enforce exhaustiveness without a default:

double area(Shape s) {
  return switch (s) {
    case Circle   c -> Math.PI * c.radius() * c.radius();
    case Square   q -> q.side() * q.side();
    case Triangle t -> 0.5 * t.base() * t.height();
  };
}

If you later add a permitted Hexagon, this switch stops compiling everywhere it appears until you handle the new case. That's exactly the safety net default would silently destroy.

When to seal

Reach for sealing when the abstraction is genuinely a closed set of cases:

  • AST or expression nodes (Literal, Add, Multiply...).
  • Domain results that are "success or one of these failures."
  • Command/event hierarchies where every downstream consumer needs to handle each case.

Don't seal types that are extension points — plugin interfaces, framework hooks, anything callers are expected to subtype. Sealing those defeats their purpose.

A worked example

java— editable, runs on the server

What's next

Sealing locks down the list of subtypes. The next chapter is about asking, at runtime, which subtype you actually have — the instanceof operator and its modern pattern-matching form, which is what makes the switch above so concise. Continue to Java instanceof operator.

Practice

Practice

What does declaring a class `sealed` accomplish?