式の値によって処理を分岐する – switch命令
switch(exp) {
case val1:
statements
case val2:
statements
…
default:
statements
}
exp:任意の式
val1、2…:expと比較する値
switch命令は、与えられた式(変数)の値によって、処理を分岐します。式の値は、char/byte/short/int/String/enum型のいずれかでなければなりません(ただし、String型を使えるのはJavaSE 7以降)。
たとえば以下は、変数valの値(1…3)に応じて対応するメッセージを表示します。それぞれの値に応じて実行する処理はcase句で、すべての値に合致しなかった場合に実行する処理はdefault句で表します。
- package com.example.mynavi.control;
- public class StatSwitch {
- public static void main(String[] args) {
- var val = 3;
- switch (val) {
- case 1:
- System.out.println("変数valは1です");
- break;
- case 2:
- System.out.println("変数valは2です");
- break;
- case 3:
- System.out.println("変数valは3です");
- break;
- default:
- System.out.println("変数valは1、2、3いずれでもありません");
- break;
- } // 結果:変数valは3です
- }
- }
なお、case、default句の末尾は、break命令で終わるのが原則です。さもないと、次の句が続けて実行されてしまいます。句の区切り目で、自動的にブロックを抜けるわけではない点に注意してください。
フォールスルー
ただし、あえて句の終わりに、break命令を指定しないこともあります。例えば以下のような場合です。
- switch (val) {
- case 1:
- case 2:
- ...中略...
- break;
- case 3:
- ...中略...
- break;
- }
これによって、変数valが1、または2の場合に実行する命令群を表現できます。このような書き方をフォールスルーと言います。
Java14以降の新構文
Java 14以降では、switch命令に新たな構文が追加されました。
- package com.example.mynavi.control;
- public class StatSwitchNew {
- public static void main(String[] args) {
- var lang = "Ruby";
- String category = switch(lang) {
- case "PHP", "Python", "Ruby" -> "スクリプト言語";
- case "Java", "C#", "C" -> "プログラミング言語";
- default -> "不明";
- };
- System.out.println(category); // 結果:スクリプト言語
- }
- }
ポイントとなる構文は、以下です。
(1)switch式
switchが式として表現できます。つまり、文の中でswitch命令を記述できます。なお、switch式では値を返さないパターンがあってはいけないので、default句は省略不可です。
(2)アロー演算子
case/default句を「値 -> 対応する式」の形式で表せます。アロー演算子では、句の末尾のbreak命令は不要となります。
(3)case値の複数列記
case句に、カンマ区切りで値を列記できます。従来のようにcase句そのものを列記する必要はありません。
switchによるパターンマッチング
Java 21以降では、case句にリテラル値だけでなく、型を指定することも可能です。たとえば以下は、変数dataがDouble型の場合は整数に丸めた値を、String型の場合は先頭5文字を抜き出した結果を、nullの場合はその旨を、それぞれメッセージ表示する例です。
StatPattern.java
- package com.example.mynavi.control;
- public class StatPattern {
- public static void main(String[] args) {
- Object data = 12.345;
- System.out.println(
- switch(data) {
- ★case Double d -> Math.floor(d);★
- case String s -> s.substring(0, 5);
- case null -> "null value...";
- default -> "Unknown Type!!";
- }
- ); // 結果:12.0
- }
- }
型を判定するには、「case 型名 変数」の形式でcase句を表します。指定された型に合致した場合、「変数」はそれぞれ対応するDouble、String型と見なされるので、型に応じたfloor、substringなどのメソッドを呼び出せる点に注目です。
型判定の構文には、条件式を加えることも可能です。たとえば以下は、先ほどのコード太字を条件式付きで書き換えたものです。
- case Double d ★when d < 10★ -> Math.floor(d);
これで式の値が「Double型で、10未満であること」という意味になります。結果、変数dataの値がマッチしなくなるため、結果は「Unknown Type!!」に変化します。
監修