本文へスキップ
BecomeCoder

Javaデザインパターンコース · 第5章 モダンJavaとパターン ― 言語機能で置き換えられるもの · レッスン14

パターンマッチング ― instanceofとswitchが型を教えてくれる

ローカル実施

導入

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 が効いてきます。ShapesealedCircleSquareTriangle の3つだけと分かっていれば、switchdefault を書かなくても「全部のケースを網羅している」ことをコンパイラが検証してくれます。もし新しい実装クラスpermits に追加し忘れたり、switch の分岐に足し忘れたりすると、コンパイルエラーで気づけます。
  • これはFactory Methodの弱点(「新しい種類を追加したとき、分岐の追加漏れに気づきにくい」)を、言語機能側から補強する組み合わせです。