switch文

switch文による条件分岐

if〜else文の入れ子を使えば、処理の流れをいくつにも分岐することができました。 しかし、場合によってはswitch文を使った方が明解に記述することができます。

キーボードから入力されたOSの種類に応じてメッセージを表示するプログラムを考えてみましょう。 まずは、If〜else文を使ったものです。

IfSample07.java
import java.io.*;

class IfSample07 {
    public static void main(String[] args) throws IOException{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        
        System.out.println("どのOSをお使いですか。番号を入力してください。");
        System.out.println("0…Windows / 1…Mac OS X / 2…Linux / 3…その他のOS");
        int num = Integer.parseInt(br.readLine());
        
        if(num == 0){
            System.out.println("こんにちは、Windowsユーザーさん。");
        }else if(num ==1){
            System.out.println("こんにちは、Macユーザーさん。");
        }else if(num == 2){
            System.out.println("こんにちは、Linuxユーザーさん。");
        }else if(num == 3){
            System.out.println("こんにちは、?OSユーザーさん。");
        }else{
            System.out.println("番号は0から3までです。");
        }
    }
}
IfSample07の実行結果 1
どのOSをお使いですか。番号を入力してください。
0…Windows / 1…Mac OS X / 2…Linux / 3…その他のOS
0
こんにちは、Windowsユーザーさん。
IfSample07の実行結果 2
どのOSをお使いですか。番号を入力してください。
0…Windows / 1…Mac OS X / 2…Linux / 3…その他のOS
4
番号は0から3までです。

では、いよいよswitch文について解説しましょう。

一般に、switch文は次のような構文になります。

構文 : switch文
switch(式){
    case 値1:
        文1
        ...
        break;
    case 値2:
        文2
        ...
        break;
    ...
    default:
        文A
        ...
        break;
}
図 6-7 : switch文のフローチャート

この構文中に現れる break; のことをbreak文と呼びます。 この構文では、式の値が値1と一致すれば、文1からbreak文までの処理が実行されます。 式の値が値2と一致すれば、文2からbreak文までが処理されます。 式の値がcaseの後のどの値とも一致しなければ、 default: の直後の文Aからbreak文までの処理が実行されることになります。 いずれの場合も、break文までくると、プログラムの流れはブロックから抜け出して、その次に書かれている文が実行されていくことになります。

式の値は、char、byte、short、intのいずれかの型でなければなりません。 また、 default: の処理は、省略することもできます。

IfSample07と同じ機能のプログラムをswitch文を使って書くと次のようになります。

SwitchSample01.java
import java.io.*;

class SwitchSample01 {
    public static void main(String[] args) throws IOException{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        
        System.out.println("どのOSをお使いですか。番号を入力してください。");
        System.out.println("0…Windows / 1…Mac OS X / 2…Linux / 3…その他のOS");
        int num = Integer.parseInt(br.readLine());
        
        switch(num){
            case 0:
                System.out.println("こんにちは、Windowsユーザーさん。");
                break;
            case 1:
                System.out.println("こんにちは、Macユーザーさん。");
                break;
            case 2:
                System.out.println("こんにちは、Linuxユーザーさん。");
                break;
            case 3:
                System.out.println("こんにちは、?OSユーザーさん。");
                break;
            default:
                System.out.println("番号は0から3までです。");
                break;
        }        
    }
}

SwitchSample01の実行結果は、IfSample07と全く同じになります。 例えば、「0」を入力すると、 case 0: の後の文が実行され、「こんにちは、Windowsユーザーさん。」と表示されます。 さらに、その次のbreak文により、ブロックを抜けます。 ブロックの後には何も書かれていませんから、そのままプログラムが終了することになります。 実際にいろいろな番号を入力して結果を確かめてみてください。

IfSample07とSwitchSample01のコードを比較すると、SwitchSample01の方がプログラムの意図をより明解に表現できているのがお分かりでしょう。

if〜else文とswitch文のどちらを使っても記述できる条件分岐では、switch文を使った方がわかりやすいコードが書けることが多い。

break文を書かないとどうなるか

では、次にbreak文を書かないとどうなるのかを試してみましょう。 break文を1つだけコメントアウトしてみます。

SwitchSample01A.java
import java.io.*;

class SwitchSample01A {
    public static void main(String[] args) throws IOException{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        
        System.out.println("どのOSをお使いですか。番号を入力してください。");
        System.out.println("0…Windows / 1…Mac OS X / 2…Linux / 3…その他のOS");
        int num = Integer.parseInt(br.readLine());
        
        switch(num){
            case 0:
                System.out.println("こんにちは、Windowsユーザーさん。");
                //break;
            case 1:
                System.out.println("こんにちは、Macユーザーさん。");
                break;
            case 2:
                System.out.println("こんにちは、Linuxユーザーさん。");
                break;
            case 3:
                System.out.println("こんにちは、?OSユーザーさん。");
                break;
            default:
                System.out.println("番号は0から3までです。");
                break;
        }        
    }
}

実行するとおかしな結果になってしまいます。

SwitchSample01Aの実行結果
どのOSをお使いですか。番号を入力してください。
0…Windows / 1…Mac OS X / 2…Linux / 3…その他のOS
0
こんにちは、Windowsユーザーさん。
こんにちは、Macユーザーさん。

switch文では、break文かブロックの最後に到達するまで、次々に文を実行していきます。 そのため、 case 0: の後のbreak文を無くしてしまうと、 case 1: 以降の文まで実行していくのです。 そして、 case 1: の後のbreak文に到達したときに、処理の流れはやっとブロックから抜け出すことになります。 このように、break文を付け忘れると、思わぬ結果を招いてしまうので注意しましょう。

しかし、このことを逆手にとって、わざとbreak文を付けない場合も考えられます。 SwitchSample01では、OSの種類を番号によって入力していましたが、OSの頭文字を入力するように変更してみましょう。

SwitchSample02.java
import java.io.*;

class SwitchSample02 {
    public static void main(String[] args) throws IOException{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        
        System.out.println("どのOSをお使いですか。頭文字を入力してください。");
        System.out.println("W…Windows / M…Mac OS X / L…Linux / X…その他のOS");
        char initial = br.readLine().charAt(0);
        
        switch(initial){
            case 'w':
            case 'W':
                System.out.println("こんにちは、Windowsユーザーさん。");
                break;
            case 'm':
            case 'M':
                System.out.println("こんにちは、Macユーザーさん。");
                break;
            case 'l':
            case 'L':
                System.out.println("こんにちは、Linuxユーザーさん。");
                break;
            case 'x':
            case 'X':
                System.out.println("こんにちは、?OSユーザーさん。");
                break;
            default:
                System.out.println("頭文字はW、M、L、Xのいずれかです。");
                break;
        }        
    }
}

今回は、

        char initial = br.readLine().charAt(0);

という部分にも注目してください。

        br.readLine()

によって得られるのはあくまでも文字列です。 ですから、

        br.readLine().charAt(0);

という処理によって、得られた文字列の1文字目を取得して、それをinitialへ代入しているのです。

それでは、実行してみましょう。頭文字「M」を入力した場合は、次のようになります。

SwitchSample02の実行結果 1
どのOSをお使いですか。頭文字を入力してください。
W…Windows / M…Mac OS X / L…Linux / X…その他のOS
M
こんにちは、Macユーザーさん。

「m」ではどうでしょうか。

SwitchSample02の実行結果 2
どのOSをお使いですか。頭文字を入力してください。
W…Windows / M…Mac OS X / L…Linux / X…その他のOS
m
こんにちは、Macユーザーさん。

頭文字「m」を入力した場合は、 case 'm': の後にbreak文が無いため、そのまま case 'M': の後の文が実行され、「こんにちは、Macユーザーさん。」と表示されるのです。 このように、break文を置かないことにより、複数の値に対して同じ処理をさせる手法もあることを憶えておいてください。

break文の書き忘れは思わぬ結果を招く。

break文をわざと書かないこともある。