Java 17では、継承階層を制限するためのより宣言的な方法を提供する機能として、sealedクラスとインターフェースが導入されました。すべてのサブクラスを禁止する`final`キーワードや、サブクラスを同じパッケージ内に限定するパッケージプライベートアクセスとは異なり、`sealed`モディファイアを使用すると、開発者は許可されるサブタイプを明示的にリストアップできます。例えば、`sealed`インターフェースは`permits`句を使用して、どのクラスがそれを実装できるかを正確に指定できます。これは、グラフィックスライブラリにおける異なる形状など、著者がシステム内で特定の既知の型のセットのみが使用されることを保証したい「値の種類」をモデリングする際に特に有用です。

この設計の主な技術的利点の一つは、網羅的なパターンマッチングを提供するためにswitch式と統合されていることです。switch式がsealed型に対して動作する場合、Javaコンパイラは可能なサブタイプの完全なセットを特定できます。開発者が許可されたすべてのサブタイプをカバーしていれば、コンパイラは`default`句の省略を許可します。サブタイプが不足している場合、コンパイラはビルド時にエラーを生成します。これは、ケースの不足が実行時エラーとしてのみ発見される可能性がある標準的なswitch文よりも高いレベルの安全性を提供します。このメカニズムは、データの構造が厳格に定義されているHaskellやMLなどの関数型プログラミング言語で見られる代数的データ型を反映しています。

しかし、sealedクラスの実用的な適用には、APIの安定性と独立したコンパイルに関する重要なトレードオフが含まれます。コンパイラはフルビルド中に網羅性を強制しますが、sealed階層に新しいサブタイプが追加された際に消費者のコードが再コンパイルされない場合、それを強制することはできません。ライブラリの著者が公開APIに新しいサブタイプを追加した場合、コードを更新していない消費者は実行時に`MatchException`に遭遇する可能性があります。このリスクがあるため、sealed型は、コードベース全体が一緒に再コンパイルされるコンポーネントの内部実装において最も効果を発揮することが多いです。公開APIとして公開される場合、新しいサブタイプの追加は破壊的な変更となり、すべての消費者が新しいケースを認識し、それに応じてパターンマッチを更新できるように、メジャーバージョンの更新が必要になる可能性があります。

さらに、Javaのパターンマッチングは、再帰的パターンやリテラルパターンのサポートとともに進化し続けています。これらの機能により、入れ子になったパターン(例:別のレコードを含むレコードをマッチングする)やswitch内のリテラル値など、より複雑なマッチングロジックが可能になります。これらの進歩は、言語の核となるオブジェクト指向の基礎を維持しながら、Javaの表現能力をKotlinやTypeScriptのようなモダンな言語に近づけることを目的としています。sealed型とこれらの高度なパターンを組み合わせることで、Javaは複雑なデータ処理において未処理のエッジケースのリスクを最小限に抑える、堅牢で型安全なロジックを作成するためのフレームワークを提供します。