Sealed Types

OOP · lesson 13 of 43 · 4 min read

How sealed types close a hierarchy so the compiler can prove your switch handles every possible case.

Open this lesson in the learning hub

Key points

  • sealed lets a type name exactly which types may extend or implement it, through its permits clause.
  • Each permitted subtype must be in the same module or package, and be final, sealed or non-sealed.
  • Records are implicitly final, so a sealed interface plus records is the standard shape for a closed set of cases.
  • Because the compiler knows every case, a switch covering them all is exhaustive and needs no default.
  • Add a new permitted type and those switches stop compiling. That is the feature: it shows you every place to update.
  • This is Java doing algebraic data types. Great for results, states and commands; wrong for open plugin points.

Example

public class Main {
    sealed interface Payment permits Card, Cash, Transfer { }

    record Card(String last4, double amount)    implements Payment { }
    record Cash(double amount)                  implements Payment { }
    record Transfer(String iban, double amount) implements Payment { }

    // The compiler knows the list is closed, so no default branch is needed.
    static String describe(Payment p) {
        return switch (p) {
            case Card c     -> "card ****" + c.last4() + " for " + c.amount();
            case Cash c     -> "cash " + c.amount();
            case Transfer t -> "transfer " + t.amount() + " to " + t.iban();
        };
    }

    public static void main(String[] args) {
        System.out.println(describe(new Card("4242", 19.99)));
        System.out.println(describe(new Cash(5)));
        System.out.println(describe(new Transfer("DE89-3704", 1200)));
        // Add a 4th Payment type and this switch stops compiling. That is the point.
    }
}

Seal a type when the case list is closed, and let the compiler check you handled them all.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the OOP course, and every lesson in it is listed on the OOP contents page.