【Java】switch文とswitch式の違いと使い方・ありがちな誤解を紹介して解説!

アイキャッチ画像

はじめに

switch文は、Javaのリリース当初(SE 1.0)から存在している機能で、Javaの基本構文の一つです。

一方、switch式はJava SE 14(2020年3月~)で正式リリースされた比較的新しい機能です。

え?switch式なんてあったの? switch文とswitch式の違いがよくわからない、そもそも文と式の違いとは?と思っているエンジニアの方は意外と多いんじゃないかと思います。この記事でその疑問を解決しましょう!

文と式の違い

switch文、switch式の前に、そもそもJavaにおける文と式とはどう違うのでしょうか。

この二つの大きな違いは「値を戻すかどうか」です。

具体例から見ていきましょう。

【文】

int num = 10; // int型変数の宣言と初期化

name = ”Nishida”;  // 変数への代入文

System.out.println(”Hello World!”); // メソッドの呼び出し文

【式】

5 + 10 // 5+10=15という戻り値(結果)がある

x += 1 // xに1を足した戻り値(結果)がある

特徴をまとめましょう。

【文】

  • 戻り値を返さなくてよい。
  • 多くの場合、文末にセミコロンが必要。

【式】

  • 計算や評価結果を返す。
  • 式単体ではセミコロンは不要。

switch文とswitch式の違い

では、switch文とswitch式の違いは?

これは、上の文と式の違いとほぼ同じで「戻り値があるかどうか」です。

戻り値がない(不要)・・・switch文

戻り値がある(必要)・・・switch式

となります。

たまに、アロー関数(矢印のような記号「->」)を使っている方がswitch式だ、と勘違いしている方がいますが間違いです。switch文でもアロー関数は使えるので、アロー関数かどうかでswitch文とswitch式を区別することはできません。

結局、戻り値を返しているかどうかで判断するのが早いし確実です。

それでは、switch文のコード例から見ていきましょう。

switch文のコード例

public static void main(String[] args) {
        int day = 2;
        String dayName;
        switch (day) {
            case 1: dayName = “Monday”;
            break;
            case 2: dayName = “Tuesday”;
            break;
            case 3: dayName = “Wednesday”;
            break;
            default: dayName = “Unknown”;
            break;        }
        System.out.println(dayName);
    // 表示
    // Tuesday

これをアロー関数を用いたバージョンに変えるとこうなります。

int day = 1;
String dayName;
switch (day) {
case 1 -> dayName = “Monday”;
    case 2 -> dayName = “Tuesday”;
    case 3 -> dayName = “Wednesday”;
    default -> dayName = “Unknown”;
  }
 System.out.println(dayName);

変更点は、

  • コロンをアローに変更
  • breakが不要(書いたらエラーになる)

switch式のコード例

int day = 2;
String dayName;
dayName = switch (day) {
    case 1 -> “Monday”;
   case 2 -> “Tuesday”;
    case 3 ->  “Wednesday”;
    default ->  “Unknown”;
  }; // ここのセミコロンを忘れないように注意 
System.out.println(dayName);
 // 表示
 // Tuesday

アロー関数を使っているという点で上のswitch文に似ていますが、

戻り値をdayNameに代入している、caseに対応する処理が式ではなく文という点が異なります。

また、System.out.println(dayName);の上の文末のセミコロンを新たに追加する必要があります。

このセミコロンが必要な理由は、dayName = switch (day) { (中略) } が全体として代入文となっているからです。最初の方で説明した通り、文の場合は文末にセミコロンが必要なので、この場所にセミコロンを記述しなければいけません。ここのセミコロンは書き忘れやすいので注意しましょう。

switch式では、それぞれのcaseに長い処理を記述することもできます。

以下を見てみましょう。

int result = 11;
String evaluate = switch(result) {
case 10 -> “最高評価”;
    case 8,9 -> “高評価”;
    case 6,7 -> “やや高評価”;
    case 5 -> “ふつう”;
    case 3,4 -> “やや低評価”;
    case 1,2 -> “低評価”;
    default -> {
        System.out.println(“点数の入力が正しくありません”);
        System.out.println(“1から10までの整数を入力してください。”);
        yield “評価不可”;
        }
    };
System.out.println(“結果:” + evaluate);

// 表示結果
// 点数の入力が正しくありません
// 1から10までの整数を入力してください。
// 結果:評価不可

アロー関数の直後に波括弧でくくり、その中で普通のメソッドのような処理を書くことができます。

yieldが使われていますが、これはJavaにおいては現状switch式の中でのみ使われる「returnの代わり」のようなものです。returnをしてしまうとswitch式自体から抜けてしまうため、戻り値として渡したい値をyiedで指定します。

なお、switch式全体が戻り値となるため、以下のようにswitch式の結果を直接returnすることもできます。

class switchRule {
public static String switchResult(int result) {
        return switch(result) {
            case 10 -> “最高評価”;
            case 8,9 -> “高評価”;
            case 6,7 -> “やや高評価”;
            case 5 -> “ふつう”;
            case 3,4 -> “やや低評価”;
            case 1,2 -> “低評価”;
            default -> {
                System.out.println(“点数の入力が出しくありません”);
                System.out.println(“1から10までの整数を入力してください。”);
                yield “評価不可”;
            }
        };
    }
}
public class Main {
    public static void main(String[] args) {
        String result = SwitchRule.switchResult(8);
        System.out.println(result);
// 表示結果
// 高評価

まとめ

switch文とswitch式について解説しました。

どちらを使っても殆ど処理に変わりはないので、状況に応じて使い分けられるようにしておくとよいでしょう。