3 Switch式
Java SE 12ではswitch
式が導入されており、この式は(すべての式と同様に)単一の値として評価され、文で使用することができます。また、"矢印case
"ラベルも導入され、これによりフォール・スルーを防ぐためのbreak
文は必要なくなりました。この機能に対する開発者のフィードバックに基づいて、Java SE 13ではswitch
式に変更が1つ導入されています。それらの値を指定するには、break
文ではなく新しいyield
文を使用してください。
注意:
これは、設計、仕様および実装は完了しているが、永続的でないプレビュー機能であり、将来のJDKリリースでは別の形式で存在するか、完全になくなる可能性があることを意味します。プレビュー機能が含まれているコードをコンパイルして実行するには、追加のコマンド行オプションを指定する必要があります。「プレビュー機能」を参照してください。switch
式の設計に関する背景情報は、JEP 354を参照してください。
曜日の文字数を出力する次のswitch
文について検討してみます。
public enum Day { SUNDAY, MONDAY, TUESDAY,
WEDNESDAY, THURSDAY, FRIDAY, SATURDAY; }
// ...
int numLetters = 0;
Day day = Day.WEDNESDAY;
switch (day) {
case MONDAY:
case FRIDAY:
case SUNDAY:
numLetters = 6;
break;
case TUESDAY:
numLetters = 7;
break;
case THURSDAY:
case SATURDAY:
numLetters = 8;
break;
case WEDNESDAY:
numLetters = 9;
break;
default:
throw new IllegalStateException("Invalid day: " + day);
}
System.out.println(numLetters);
曜日名の長さは、変数numLetters
に格納するかわりに値を戻せた方が便利で、これはswitch
式を使用して行うことができます。また、フォール・スルーを防ぐのに、記述が面倒で付け忘れがちなbreak
文が必要がなくなれば、さらに便利です。これは、新しい種類のcase
ラベルで実現できます。次のswitch
式では、新しい種類のcase
ラベルを使用して、曜日の文字数を出力します。
Day day = Day.WEDNESDAY;
System.out.println(
switch (day) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
case THURSDAY, SATURDAY -> 8;
case WEDNESDAY -> 9;
default -> throw new IllegalStateException("Invalid day: " + day);
}
);
新しい種類のcase
ラベルの形式は次のとおりです。
case label_1, label_2, ..., label_n -> expression;|throw-statement;|block
Javaランタイムが矢印の左側にある任意のラベルに一致すると、矢印の右側にあるコードが実行されて、フォール・スルーしません。つまり、switch
式(または文)内の他のコードは実行されません。矢印の右側のコードが式である場合、その式の値はswitch
式の値になります。
新しい種類のcase
ラベルをswitch
文で使用できます。次の例は最初の例と同様ですが、「コロンcase
」ラベルのかわりに「矢印case
」ラベルが使用されています。
int numLetters = 0;
Day day = Day.WEDNESDAY;
switch (day) {
case MONDAY, FRIDAY, SUNDAY -> numLetters = 6;
case TUESDAY -> numLetters = 7;
case THURSDAY, SATURDAY -> numLetters = 8;
case WEDNESDAY -> numLetters = 9;
default -> throw new IllegalStateException("Invalid day: " + day);
};
System.out.println(numLetters);
「コロンcase
」ラベルは、次のようにswitch
式で使用できます。
Day day = Day.WEDNESDAY;
int numLetters = switch (day) {
case MONDAY:
case FRIDAY:
case SUNDAY:
System.out.println(6);
yield 6;
case TUESDAY:
System.out.println(7);
yield 7;
case THURSDAY:
case SATURDAY:
System.out.println(8);
yield 8;
case WEDNESDAY:
System.out.println(9);
yield 9;
default:
throw new IllegalStateException("Invalid day: " + day);
};
System.out.println(numLetters);
Java SE 13ではyield
文が導入されています。これは、1つの引数(case
ラベルがswitch
式で生成する値)を取ります。
yield
文により、switch
文とswitch
式を容易に区別できるようになります。switch
文(switch
式ではない)は、break
文のターゲットとすることができます。反対に、switch
式(switch
文ではない)は、yield
文のターゲットとすることができます。
注意:
「矢印case
」ラベルの使用をお薦めします。「コロンcase
」ラベルの使用時は、break
文またはyield
文の挿入を忘れがちです。これを忘れると、コード内で思いがけないフォール・スルーが発生する場合があります。
「矢印case
」ラベルで、複数の文または式でないコード、あるいはthrow
文を指定するには、それらをブロック内に囲みます。case
ラベルが生成する値をyield
文で指定します。
int numLetters = switch (day) {
case MONDAY, FRIDAY, SUNDAY -> {
System.out.println(6);
yield 6;
}
case TUESDAY -> {
System.out.println(7);
yield 7;
}
case THURSDAY, SATURDAY -> {
System.out.println(8);
yield 8;
}
case WEDNESDAY -> {
System.out.println(9);
yield 9;
}
default -> {
throw new IllegalStateException("Invalid day: " + day);
}
};