Sealed Types
How sealed types close a hierarchy so the compiler can prove your switch handles every possible case.
Open this lesson in the learning hubKey points
sealedlets a type name exactly which types may extend or implement it, through itspermitsclause.- Each permitted subtype must be in the same module or package, and be
final,sealedornon-sealed. - Records are implicitly final, so a
sealed interfaceplus records is the standard shape for a closed set of cases. - Because the compiler knows every case, a
switchcovering them all is exhaustive and needs nodefault. - 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.