導入
Java文法コースで学んだ instanceof は「型を確認するだけ」でした。確認した後、結局もう一度キャスト(型変換)して使う必要があり、二度手間でした。モダンJavaの パターンマッチング は、「型を確認する」と「その型として変数に取り出す」を1行でまとめてくれます。
説明
// 従来の書き方
if (shape instanceof Circle) {
Circle c = (Circle) shape; // 確認したのに、また自分でキャストする
System.out.println(c.radius);
}
// instanceofのパターンマッチング(Java 16〜)
if (shape instanceof Circle c) {
System.out.println(c.radius); // c は既に Circle 型として使える
}
// switchのパターンマッチング(Java 21〜)。sealedと組み合わせると真価を発揮する
String description = switch (shape) {
case Circle c -> "円(半径" + c.radius + ")";
case Square s -> "正方形(辺" + s.side + ")";
case Triangle t -> "三角形";
};
flowchart TD A["shape の実体は何か"] -->|Circleなら| B["c として半径を使える"] A -->|Squareなら| C["s として辺の長さを使える"] A -->|Triangleなら| D["t として扱える"]
if (shape instanceof Circle c)… 型チェックと同時に、cという新しい変数に「Circleとして」代入されます。キャストが不要になります。switch (shape) { case Circle c -> ... }… 型ごとの分岐を、キャストなしでスッキリ書けます。- ここで前のレッスンの
sealedが効いてきます。ShapeがsealedでCircle・Square・Triangleの3つだけと分かっていれば、switchはdefaultを書かなくても「全部のケースを網羅している」ことをコンパイラが検証してくれます。もし新しい実装クラスをpermitsに追加し忘れたり、switchの分岐に足し忘れたりすると、コンパイルエラーで気づけます。 - これはFactory Methodの弱点(「新しい種類を追加したとき、分岐の追加漏れに気づきにくい」)を、言語機能側から補強する組み合わせです。