Skip to content
  • Sealed Classes & Interfaces · Java

Sealed Classes & Interfaces

LearnViaNotes @learnvianotes· 3 min read

A sealed type (Java 17) lists exactly which classes may extend it. The compiler then knows the full set of subtypes — which makes switch over them exhaustive.

Why seal a hierarchy?

Subtype modifiers

Permitted subtype is…Meaning
finalNo further subclasses (records and enums are implicitly final)
sealed … permits …Continues the restriction one level down
non-sealedRe-opens that branch — anyone may extend it

Sealed interface + records + pattern switch

Java
public class Main {
    sealed interface Shape permits Circle, Square, Rect {}
    record Circle(double r) implements Shape {}
    record Square(double side) implements Shape {}
    record Rect(double w, double h) implements Shape {}

    static double area(Shape s) {
        return switch (s) {                    // exhaustive: no default
            case Circle c -> Math.PI * c.r() * c.r();
            case Square sq -> sq.side() * sq.side();
            case Rect(double w, double h) -> w * h;     // record pattern (Java 21)
        };
    }

    public static void main(String[] args) {
        Shape[] shapes = { new Circle(1), new Square(2), new Rect(2, 3) };
        for (Shape s : shapes) System.out.printf("%s -> %.2f%n", s, area(s));
    }
}
Output
Circle[r=1.0] -> 3.14
Square[side=2.0] -> 4.00
Rect[w=2.0, h=3.0] -> 6.00

Sealed classes with final / non-sealed

Java
public class Main {
    static abstract sealed class Vehicle permits Car, Truck {}
    static final class Car extends Vehicle {}
    static non-sealed class Truck extends Vehicle {}      // open again
    static class Pickup extends Truck {}                  // allowed: Truck is non-sealed

    static String describe(Vehicle v) {
        return switch (v) {
            case Car c -> "car";
            case Truck t -> "truck (" + t.getClass().getSimpleName() + ")";
        };
    }

    public static void main(String[] args) {
        System.out.println(describe(new Car()));
        System.out.println(describe(new Pickup()));
    }
}
Output
car
truck (Pickup)

Trying to extend a sealed type

Java
public class Main {
    sealed interface Shape permits Circle {}
    record Circle(double r) implements Shape {}
    record Triangle(double b, double h) implements Shape {}   // not in permits

    public static void main(String[] args) {}
}
Compiler error
Main.java:4: error: class is not allowed to extend sealed class: Shape (as it is not listed in its 'permits' clause)
    record Triangle(double b, double h) implements Shape {}   // not in permits
    ^
  • Permitted subclasses must be in the same module (or the same package in the unnamed module).

  • If all subtypes are in the same source file, the permits clause can be omitted — the compiler infers it.

  • Every permitted subtype must directly extend/implement the sealed type.

Sealed class vs final class vs enum?

What does sealing buy you in a switch?

Free for students and teachers

Write notes like this one

Cards for every idea, quizzes and flashcards, read aloud — on the web and your phone.

Something wrong with this note? Open it to report