switch のパターン
Sealed 型とパターンを組み合わせます。
「switch のパターン」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。
switch でパターンを使う
switch は定数にマッチするだけでなく、パターンにもマッチできるようになりました。sealed 型やレコードと組み合わせると、switch で型による振り分けやデータの分解を行い、網羅性も保証できます。
switch の型パターン
各 case に型パターンを指定し、その分岐用の型付き変数を束縛できます。
public class Main {
static String kind(Object o) {
return switch (o) {
case Integer i -> "int " + i;
case String s -> "string " + s;
default -> "other";
};
}
public static void main(String[] args) {
System.out.println(kind(42));
System.out.println(kind("hi"));
System.out.println(kind(3.14));
}
}sealed 型では default が不要
セレクターが sealed 型で、許可されたすべてのサブタイプを網羅している場合、default がなくても switch は網羅的になります。
public class Main {
sealed interface Shape permits Circle, Square {}
record Circle(double r) implements Shape {}
record Square(double s) implements Shape {}
static double area(Shape shape) {
return switch (shape) {
case Circle c -> Math.PI * c.r() * c.r();
case Square sq -> sq.s() * sq.s();
};
}
public static void main(String[] args) {
System.out.printf("%.2f%n", area(new Square(3)));
}
}case でレコードパターンを使う
case ではレコードを分解し、コンポーネントを分岐本体から直接利用できます。
public class Main {
sealed interface Shape permits Circle, Rectangle {}
record Circle(double r) implements Shape {}
record Rectangle(double w, double h) implements Shape {}
static double area(Shape shape) {
return switch (shape) {
case Circle(double r) -> Math.PI * r * r;
case Rectangle(double w, double h) -> w * h;
};
}
public static void main(String[] args) {
System.out.printf("%.2f%n", area(new Rectangle(2, 5)));
}
}when によるガード
when 節を使うと、case にブール値のガードを追加できます。パターンに適合し、かつガードが true の場合にだけ case がマッチします。
public class Main {
static String size(Object o) {
return switch (o) {
case Integer i when i < 0 -> "negative";
case Integer i when i == 0 -> "zero";
case Integer i -> "positive";
default -> "not an int";
};
}
public static void main(String[] args) {
System.out.println(size(-5));
System.out.println(size(0));
System.out.println(size(7));
}
}ガードでは順序が重要
ガード付き case は上から下の順に試されます。より具体的なガード付き case は、より広いガードなしの case より前に置く必要があります。そうしないと、広い case に先に取り込まれてしまいます。
null を処理する
null のセレクターを処理するには case null を追加します。追加しない場合、switch は NullPointerException をスローします。case null, default のように組み合わせることもできます。
public class Main {
static String label(String s) {
return switch (s) {
case null -> "missing";
case "yes" -> "affirmative";
default -> "other: " + s;
};
}
public static void main(String[] args) {
System.out.println(label(null));
System.out.println(label("yes"));
System.out.println(label("maybe"));
}
}switch でネストしたパターンを使う
case ではレコードパターンをネストして、深い構造にマッチし、内側の値に対するガードを1か所で記述できます。
public class Main {
record Point(int x, int y) {}
record Line(Point a, Point b) {}
static String describe(Object o) {
return switch (o) {
case Line(Point(var x1, var y1), Point(var x2, var y2)) when x1 == x2 -> "vertical";
case Line(Point a, Point b) -> "line";
default -> "other";
};
}
public static void main(String[] args) {
System.out.println(describe(new Line(new Point(1, 0), new Point(1, 5))));
System.out.println(describe(new Line(new Point(0, 0), new Point(2, 3))));
}
}文と式
パターン switch は式としても文としても使えます。式では -> または yield によって値を生成します。セレクターが sealed 型の場合は、網羅性のルールが適用されます。
Visitor コードを置き換える
sealed 型とパターン switch を組み合わせると、冗長な Visitor パターンや instanceof の連鎖を、閉じたモデルに対する簡潔でコンパイラー検証済みの振り分けに置き換えられます。
完全なインタープリター
sealed 型のモデルとパターン switch を使った式評価器です。
public class Main {
sealed interface Expr permits Num, Add, Mul {}
record Num(int value) implements Expr {}
record Add(Expr left, Expr right) implements Expr {}
record Mul(Expr left, Expr right) implements Expr {}
static int eval(Expr e) {
return switch (e) {
case Num(int v) -> v;
case Add(Expr l, Expr r) -> eval(l) + eval(r);
case Mul(Expr l, Expr r) -> eval(l) * eval(r);
};
}
public static void main(String[] args) {
Expr e = new Add(new Num(2), new Mul(new Num(3), new Num(4)));
System.out.println(eval(e));
}
}理解度チェック
switch でのパターンの理解度を確認しましょう。
まとめ
switch でのパターンについて学びました。
- case では型パターンやレコードパターンを使い、データを分解できます。
- sealed 型のセレクターでは、
defaultなしで網羅的な switch を記述できます。 whenガードで case をより絞り込めます。順序も重要です。case nullで null を安全に処理できます。
AI チューターと学ぶ Java — 無料
ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。
- コース
- 104
- レッスン
- 374
よくある質問
「switch のパターン」レッスンは無料ですか?
はい。「switch のパターン」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。
「switch のパターン」で何を学びますか?
Sealed 型とパターンを組み合わせます。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Java Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「switch のパターン」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このJava Academyレッスンでコードを書いて実行できますか?
はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。