RAKUS Developers Blog | ラクス エンジニアブログ

株式会社ラクスのITエンジニアによる技術ブログです。

Java14からswitchがより便利に

id:logy0704です。

もうすぐJava14がリリースされますね。

いくつかの変更が予定されていますが、その中でも今回はswitch文の変更についてご紹介しようと思います。*1

そもそもswitch文って?

Javaを学んだことのある方ならば一度は触れたことがあるかと思います。

以下のような形式で複数分岐を表現することができ、特にEnumと組み合わせて使われることが多いです。

switch(case) {
    case1:
        hoge;
        break;
    case2:
        huga;
        break;
    default:
        piyo;
}

従来のswitch文の課題

fall through

switch文ではマッチしたラベル以降の分岐がすべて実行されてしまいます。

一つの分岐のみ実行したい場合にはbreak文を追加してあげる必要があります。 *2

ブロック

switch文ではブロック全体が一つのスコープとみなされるため、変数名の競合や想定外の再代入が発生する可能性がありました。 *3

文であること

switch文(switch statement)と表現されるように、これまではswitchは文としてのみ扱われてきました。 *4

そのため、条件によって変数を変化させたい場合、switch文をそのまま変数に設定することはできず、一度、switch文の中で変数に値を設定してから利用する必要がありました。

int hoge;

switch(case) {
    case1:
        hoge = "huga";
        break;
    case2:
        hoge = "piyo";
        break;
    default:
}

System.out.println(hoge);

これからのswitch

これらの課題を解消するため、switchに変更が加えられました。*5

※ サンプルコードは https://openjdk.java.net/jeps/361 から引用させていただきました。

矢印構文の導入

ラムダ式で見かけるような矢印を使った記法が導入されました。

switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);
    case TUESDAY                -> System.out.println(7);
    case THURSDAY, SATURDAY     -> System.out.println(8);
    case WEDNESDAY              -> System.out.println(9);
}

label -> 実行したい内容 という構文でそれぞれの条件分岐を表現することができます。

カンマ区切りで複数のラベルを並べることで、複数ケースにマッチする条件も表現できます。

この構文の場合、break文は必要とせず、一度条件にマッチした後、switchから離脱します。

見た目もスッキリするだけでなく、うっかりbreak文を書き忘れて想定外のバグが…なんてことがなくなりますね。

また、変数のスコープもそれぞれの矢印の右辺に閉じるため、変数名の重複等に気を使う必要がなくなりました。

式として扱えるように

switchの結果を引数に渡したり、変数に格納することが出来るようになります。

static void howMany(int k) {
    System.out.println(
        switch (k) {
            case  1 -> "one"
            case  2 -> "two"
            default -> "many"
        }
    );
}

最後に

switchの新たな記法についてご紹介しました。

Java14はLTSではないため、まだ導入される方は少ないかもしれませんが、将来的に利用できる記法として頭の片隅に置いておくと良いかもしれません。

参考

*1:Java12からプレビュー版として提供されていた内容ですが、フィードバックを経てJava14で正式導入されます。

*2:あえてbreak文を書かないことで複数の条件にマッチさせるような書き方もできます。

*3:各ラベルごとにブロックを区切ってあげることで回避する方法が一応存在します。

*4:Javaにおける文の正確な定義についてはOracle社公式ページを参照してください。

*5:正確には課題の解消だけでなく、現在プレビュー中のパターンマッチング機能への布石としての側面もあるようです。

Copyright © RAKUS Co., Ltd. All rights reserved.