Java sealed classes and exhaustive pattern matching

180 points · 144 comments on HN · read original →

Points and comments are a snapshot, not live.

Java's sealed classes enable exhaustive pattern matching but introduce new breaking-change risks across module boundaries.

Java 17 sealed classes allow explicit sub-type lists and enable compiler exhaustiveness checking for switch expressions, eliminating the need for default clauses. However, adding a new subtype to a sealed type breaks consumers at compile time only if they recompile. Without recompilation, a MatchException is thrown at runtime, as demonstrated by adding a TypeC case. The author concludes sealed types are most useful within a component's internal implementation, not in public APIs, citing the JDK's PEM-encoded cryptographic objects preview as a risky example.

The post notes that while sealed classes improve compile-time safety for internal use, they introduce new ways to break code when used across module boundaries, with breakage only detectable at runtime if consumers aren't recompiled.

What commenters are saying

The comment thread is dominated by a defense of Java's evolution strategy from what appears to be a JDK team member, who argues Java deliberately avoids feature richness and that sealed classes and pattern matching derive from ML, not Kotlin. Other commenters counter that Java's pace is glacial and its features are "weaksauce" compared to Kotlin. A third group notes Java has improved its release cadence significantly. One commenter praises Java's approach to virtual threads over Kotlin's coroutines. The thread also notes Kotlin lacks destructuring in pattern matching, which some consider a basic requirement.