問題の歴史
パターンマッチングは、型をチェックし、データを一度のステップで抽出できる、関数型およびスクリプト言語から借用された技法です。Javaにおけるパターンマッチングの発展は、Java 14から始まり(プレビュー機能)、Java 16-17で改善され、最新のリリースではswitch構文にも拡張されています。
問題点
従来の型チェックとキャストの方法は冗長でした:
if (obj instanceof String) { String s = (String) obj; ... }
余分な変数が発生し、大量のテンプレートコードと型キャストのエラーリスクがありました。
解決策
パターンマッチングでは、型チェック、新しい変数の宣言、及びその使用を1つの式で結合できます:
if (obj instanceof String s) { System.out.println(s.length()); }
同様のパターンがswitch構文にも現れるようになり、コードはより簡潔になり、エラーの可能性が減ります。
主な特徴:
カスタム(ユーザー定義)クラスに対してパターンマッチングを使用できますか、それとも標準型のみに限られますか?
任意のクラスに対して使用することができます。パターンマッチングは、instanceofを適用できるすべてのクラスで機能します。
パターン変数はif/switchブロック外でアクセス可能ですか?
いいえ、パターンマッチング内で宣言された変数は、作成されたブロック(例えばifまたはcase switch)内でのみ見ることができます。
コードの例:
if (obj instanceof Integer i) { // iはこのブロック内でのみ可視 System.out.println(i + 10); } // ここではiは利用できない
パターンマッチングをジェネリクスと一緒に使用できますか?
はい、以下のように使用できます:
Object list = List.of("a", "b"); if (list instanceof List<?> l) { System.out.println(l.size()); }
ただし、raw型やパラメータ化された型へのキャストは、型消去のためまだ制限されています。
チームは全てのケースでパターンマッチングを導入し、内部DTO、サービスクラス、ポリモルフィズムだけで十分なケースを含めました。コードはinstanceofに過度に依存し、クラス階層の役割が曖昧になりました。
メリット:
デメリット:
プロジェクトでは、パターンマッチングは一般的なインターフェース、補助的なユーティリティ、未知の型のコレクションの処理のみに適用されました。OOPアーキテクチャは保持され、必要な場合のみパターンが使用されました。
メリット:
デメリット: