Java 17 sealed classes let a type explicitly list its permitted subtypes and, together with pattern-matching switch expressions, enable compiler exhaustiveness checking: if all declared subtypes are covered, a switch need not have a default branch. Using sealed interfaces with record implementations creates algebraic-data-type-like structures so the compiler can catch missing cases at compile time, improving safety for code compiled together. The post illustrates this with a simple sealed interface and two record cases and notes that enums behave similarly.
The problem arises when sealed types are part of a public API and consumers are not recompiled after the sealed type gains a new subtype. Separate compilation means a consumer that lacked a case for the new subtype will compile fine against the old API but throw java.lang.MatchException at runtime when the new case occurs; the Javadoc also warns about pattern null corner-cases. The practical conclusion is to prefer sealed types for internal use within a component, where everything is rebuilt together and exhaustiveness is reliable, and avoid exposing sealed hierarchies in public APIs because adding subtypes becomes a breaking change detectable only at runtime for unrebuilt clients.
Summary generated by AI from the linked article. hn.today is not affiliated with Hacker News or Y Combinator.