Java switch case文の詳しい説明

 
 
if…else ステートメントは「道の 2 つの分かれ道」を表すために使用できます。私たちはどちらか 1 つの道を選択して歩き続けることしかできませんが、人生では「複数の分かれ道」に遭遇することがよくあります。 switch ステートメントは、実行する複数のステートメント ブロックの 1 つを選択できる if ステートメントの代替形式を提供します。

 

switch ステートメントの形式

switch ステートメントは、 Javaの多方向分岐ステートメントです。これにより、式の値に基づいてプログラムでさまざまな部分を実行する簡単な方法が提供されます。したがって、一連の if-else-if ステートメントよりも優れた代替手段となります。

switch ステートメントの基本的な構文は次のとおりです。

 switch(式) {
    case 値1:
        文1;
        break;
    case 値2:
        文2;
        break;
    …
    case 値n:
        文n;
        break;
    default:
        文n+1;
    break;
} 

このうち、switch、case、default、break はすべて Java キーワードです。

1) スイッチ

「switch」を示します。このスイッチは switch キーワードの後ろのかっこ内の値であり、整数変数または文字変数はかっこ内に配置する必要があります。式は byte、short、int、char 型である必要があります。

Java7 では switch ステートメントの機能が拡張され、switch ステートメントの制御式を java.lang.String 型の変数または式にできるようになりました。タイプは java.lang.String のみにすることができ、StringBuffer や StringBuilder にすることはできません。

2) ケース

「ケース、状況」を示します。ケース ラベルは次のとおりです。

  • char、byte、short、または int 型の定数式。
  • 列挙定数。
  • Java SE 7 以降では、ケースラベルを文字列リテラルにすることもできます。

例えば:

switch (input.toLowerCase()) {  // toLowerCaseは大文字を小文字に変換するために使われます
    case "yes":
        ...
        break;
} 

switch ステートメントで列挙定数を使用する場合、各ラベルで列挙名を指定する必要はありません。列挙名はスイッチの式の値によって決定できます。例えば:

Size sz = ...;
switch (sz) {
    case SMALL: // Size.SMALLを使用する必要はありません
        ...
    ...
} 

注:重複する大文字と小文字の値は許可されません

3) Default

「Default」、つまり他の条件が満たされていないことを示します。デフォルトの後にはコロンを付ける必要がありますが、デフォルトブロックとケースブロックの順序はプログラムの実行結果に影響を与えることなく変更できます。通常、デフォルトのブロックは最後に配置されますが、省略することもできます。

4) Break

「Break」、つまり現在の構造から飛び出すことを示します。

case 分岐ステートメントの最後に Break ステートメントがない場合、複数の case 分岐をトリガーすることができます。次に、次の case 分岐ステートメントが実行されます。この状況は非常に危険であり、多くの場合エラーが発生します。このため、プログラムでは switch ステートメントを使用しません。

switch ステートメントが好きなら、次のように -Xlint:fallthrough オプションを使用してコードをコンパイルすることを検討してください。

javac -Xlint:fallthrough Test.java

このようにして、ブランチの最後に Break ステートメントが欠落している場合、コンパイラは警告メッセージを表示します。

switch ステートメントの実行は次のようになります。式の値が各 case ステートメントの定数と比較されます。一致するものが見つかった場合は、case ステートメントに続くコードが実行されます。いずれの case 定数も式の値と一致しない場合は、デフォルトのステートメントが実行されます。もちろん、default ステートメントはオプションです。一致する case ステートメントがなく、default ステートメントもない場合は、何も実行されません。

例1

番組の抽選では、番組チームが各ゲストの座席番号に応じて抽選ゲームを実施し、異なる数字に応じて賞金の大きさを決定します。 switch ステートメントを使用して賞品の配布を完了する Java プログラムを作成します。実装コードは次のとおりです。

 public static void main(String[] args) {
    System.out.println("座席番号を入力してください:");
    Scanner sc = new Scanner(System.in);
    int num = sc.nextInt();
    switch (num) {
    case 8:
        System.out.println("おめでとうございます。三等賞を獲得しました!");
        break;
    case 88:
        System.out.println("おめでとうございます。二等賞を獲得しました!");
        break;
    case 888:
        System.out.println("おめでとうございます。一等賞を獲得しました!");
        break;
    default:
        System.out.println("ご参加ありがとうございました!");
        break;
    }
} 

ユーザーが入力した数値が 888 の場合、取得される num 値は 888 で、3 番目のケース以降の値と一致し、その後ろのステートメントを実行し、「おめでとうございます、一等賞を獲得しました!」を出力し、ブレークを実行します。ステートメント 、スイッチ構造全体から。入力した数値が case の値と一致しない場合は、デフォルトの後にステートメントを実行します。

例 2

現在の週番号に応じて、対応する中国語の文字を出力する Java プログラムを作成します。ここではbreakを含むswitch文を使って今週を判定しており、実装コードは以下の通りです。

 public static void main(String[] args) {
    String weekDate = "";
    Calendar calendar = Calendar.getInstance();  // 現在時刻を取得
    int week = calendar.get(Calendar.DAY_OF_WEEK) - 1;  // 曜日を取得
    switch (week) {
        case 0:
            weekDate = "日曜日";
            break;
        case 1:
            weekDate = "月曜日";
            break;
        case 2:
            weekDate = "火曜日";
            break;
        case 3:
            weekDate = "水曜日";
            break;
        case 4:
            weekDate = "木曜日";
            break;
        case 5:
            weekDate = "金曜日";
            break;
        case 6:
            weekDate = "土曜日";
            break;
    }
    System.out.println("今日は " + weekDate + "です。");
} 

このプログラムは、まず現在の週の値を取得し、次に switch ステートメントを使用して週の値を判断します。0 は日曜日を意味し、1 は月曜日を意味し、2 は火曜日を意味します…というように、6 は土曜日を意味します。 Week 値が case 値と一致する限り、プログラムは case 内のステートメントを実行し、switch ステートメントから抜け出して、結果を出力します。

ネストされた switch ステートメント

switch ステートメントは、外側の switch ステートメントのステートメント シーケンスの一部として含めることができます。これは、ネストされた switch ステートメントと呼ばれます。 switch ステートメントは独自のブロックを定義するため、外側の switch ステートメントと内側の switch ステートメントの case 定数は競合しません。たとえば、次のプログラム部分は完全に正しいです。

 public static void main(String[] args) {
    switch (count) {
        case 1:
            switch (target) {
            case 0:
                System.out.println("ターゲットはゼロです。");
                break;
            case 1:
                System.out.println("ターゲットは1です。");
                break;
            }
            break;
        case 2: // ...
    }
} 

この例では、内側の switch ステートメントのcase 1:ステートメントは、外側の switch ステートメントのcase 1:ステートメントと競合しません。変数 count は、外側の case ステートメントとのみ比較されます。変数 count が 1 の場合、変数 target は inner case ステートメントと比較されます。

ここで次の点がわかります。

  • switch ステートメントは if ステートメントと異なり、switch ステートメントは等しいかどうかをテストすることしかできませんが、if ステートメントはあらゆるタイプのブール式を評価できます。つまり、switch ステートメントは、式の値と一致する値を case 定数の中からのみ検索できます。
  • 同じ switch ステートメント内に 2 つの同一の case 定数は存在しません。もちろん、外側の switch ステートメントの case 定数は、内側の switch ステートメントの case 定数と同じにすることもできます。
  • 通常、switch ステートメントは、ネストされた一連の if ステートメントよりも効率的です。

この最後の点は、Java コンパイラがどのように動作するかを示しているため、特に興味深いです。 switch ステートメントをコンパイルするとき、Java コンパイラは各 case 定数を調べ、式の値に基づいて実行パスを選択するために使用される「ジャンプ テーブル」を作成します。したがって、一連の値の中から選択する必要がある場合、switch ステートメントは同等の if-else ステートメントよりもはるかに高速です。

コンパイラーは、case 定数がすべて同じ型であることを認識しており、それを switch 式と比較して等しいかどうかを確認するだけで済むため、これが可能になります。一連の if 式の場合、コンパイラにはそのような機能はありません。

if文とswitch文の違い

if ステートメントと switch ステートメントは両方とも条件ステートメントを表し、使用効率と実用性の観点から区別できます。

1. 使用効率で区別する

使用効率の観点から、同じ変数の異なる値に対する条件判定を行う場合は、switch 文と if 文のどちらを使用しても問題ありません。 switch ステートメントを使用する効率は高く、特に分岐を判定する数が多いほど、その効果が顕著になります。

2. 実用性から区別する

ステートメントの実用性の観点から見ると、switch ステートメントは if 条件ステートメントほど優れたものではなく、if ステートメントが最も広く使用されており実用的なステートメントです。

3. if ステートメントと switch ステートメントを使用する場合

プログラム開発の過程において、if文やswitch文をどのようなタイミングで使用するかは、実際の状況に応じて判断し、最大限に活用するように心がけましょう。 switch 文は効率が良いため常に使用できるわけではなく、if 文がよく使われるため switch 文は使用できません。現実の状況に応じて具体的な問題を分析し、最適な条件文を使用する必要があります。

一般に、少ない判定条件であれば if 条件文を使用できますが、一部の複数の条件判定を実現する場合には switch 文を使用した方がよいでしょう。

 

「 Java switch case文の詳しい説明」についてわかりやすく解説!絶対に観るべきベスト2動画

Java で大文字と小文字を切り替える