Java道|switch文のしくみと使い方

分岐が増えたら、switch文。
値ごとの処理を整理すると、Javaの条件分岐はもっと読みやすくなる。

これまでに、if文、if~else文、if~else if~else文を使って、条件に応じて処理を切り替える方法を学んできました。

if文では、条件が true のときだけ処理を実行できました。
if~else文では、true の場合と false の場合で処理を分けられました。
if~else if~else文では、複数の条件を上から順番に判定できるようになりました。

ただ、同じ変数の値によって、1ならこの処理、2ならこの処理、3ならこの処理、というように分岐が増えてくると、if~else if~else文では少し長く見えることがあります。

このようなときに便利なのが switch文 です。

switch文は、ある式の値を調べ、その値がどの case に一致するかによって処理を切り替える構文です。値ごとの分岐を整理して書けるため、メニュー番号や選択文字のように、決まった候補から処理を選ぶ場面でとても使いやすいです。

この記事では、指定内容に沿って Sample5.java と Sample6.java のみを使い、switch文の基本、case、default、break の役割、文字を使った分岐まで、鬼滅の刃風の世界観にたとえながら整理します。

鬼滅の刃風にたとえると、switch文は「任務札の番号や記号を見て、対応する指令を選ぶ仕組み」です。
任務番号が 1 なら水の補給指令、2 なら食料補給指令、それ以外なら正しい番号を案内する。
このように、値ごとに進む道を分けられるのが switch文 です。

switch文とは何か

switch文は、ある式の値をもとに、複数の候補の中から一致する処理を選ぶ構文です。

↓クリックすると拡大表示されます。

基本の形は次のようになります。

switch(式){
    case 値1:
        文1;
        break;

    case 値2:
        文2;
        break;

    default:
        文3;
        break;
}

この構文では、まず switch の丸かっこの中にある式を評価します。

switch(式)

その結果が case の値と一致するかを見ていきます。

場所役割
switch(式)分岐の基準になる値を調べる
case 値:式の結果がその値と一致したときの処理を書く
default:どの case にも一致しなかったときの処理を書く
break;switch文の処理をそこで終わらせる

たとえば、switch(num) と書けば、num の値によって処理を分けます。
num が 1 なら case 1、num が 2 なら case 2、どれにも一致しなければ default に進みます。

鬼滅の刃風にたとえると、switch の式は「任務札の番号」です。
case は「番号ごとの指令」、default は「どの番号にも合わなかったときの通常案内」です。

if~else if~else文との違い

switch文は、if~else if~else文と似た分岐ができます。

たとえば、ある変数 num の値が 1 なら処理A、2 なら処理B、それ以外なら処理C、という分岐は、if~else if~else文でも書けます。

if(num == 1){
    処理A;
}
else if(num == 2){
    処理B;
}
else{
    処理C;
}

同じ考え方を switch文 で書くと、次のようになります。

switch(num){
    case 1:
        処理A;
        break;
    case 2:
        処理B;
        break;
    default:
        処理C;
        break;
}

どちらも、値によって処理を分けることができます。

ただし、同じ変数の値をいくつかの候補と比べるだけなら、switch文 のほうが見やすくなることがあります。

比較する内容向いている構文
score >= 80 のような大小比較if文 系
複数の条件を組み合わせるif文 系
num が 1、2、3 のどれかを見るswitch文
文字 m、n、q などで分けるswitch文

switch文は、「この値ならこの処理」という分岐を並べたいときに便利です。

鬼滅の刃風にたとえると、if~else if~else文は「状況を順番に確認する判断」、switch文は「任務札の番号と指令表を照合する判断」です。

switch文の流れ

switch文の流れは、次のように考えると分かりやすいです。

順番処理
1switch の式を評価する
2case の値と比べる
3一致した case から処理を始める
4break に出会ったら switch文を抜ける
5どの case にも一致しなければ default を実行する

たとえば、switch(num) の場合、num の値を見て、case 1、case 2、default のどこへ進むかを決めます。

switch(num){
    case 1:
        文1;
        break;
    case 2:
        文2;
        break;
    default:
        文3;
        break;
}

num が 1 なら case 1 の処理を実行します。
num が 2 なら case 2 の処理を実行します。
どちらにも一致しなければ default の処理を実行します。

ここで大切なのが break です。
break があることで、処理が終わったあとに switch文 から抜けられます。

図:switch文は値に応じてcaseを選ぶ

↓クリックすると拡大表示されます。

この図が示していること

この図では、switch(num) の値によって、どの case に進むかが決まることを示しています。

num が 1 なら case 1 に進み、飲み物メニューを表示します。
num が 2 なら case 2 に進み、軽食メニューを表示します。
どちらにも一致しない場合は default に進み、1か2を入力してください。 と表示します。

また、それぞれの処理のあとに break があることで、switch文から抜ける流れも確認できます。

ここから分かることは、switch文は「値に応じて処理を選ぶ構文」だということです。

switch文が便利な場面

switch文は、1つの変数や式の値によって、複数の決まった候補に分岐したいときに便利です。

たとえば、次のような場面です。

場面分岐の例
メニュー番号1なら飲み物、2なら軽食、その他なら案内
曜日番号1なら月曜日、2なら火曜日
選択文字mなら任務開始、nなら中止
コード番号100なら成功、200なら警告
任務番号1なら補給、2なら警戒、その他なら再入力

if~else if~else文でも同じような処理は書けます。
ただし、同じ変数の値をいくつかの候補と比べるなら、switch文にすると構造が見えやすくなります。

鬼滅の刃風にたとえると、switch文は「任務番号ごとの指令表」です。
番号が決まっていて、その番号に応じて処理を振り分ける場面で使いやすいです。

switch文を確認する

ここでは、入力された数字によって、異なる案内メッセージを表示するプログラムを見ていきます。

ファイル名:Sample5.java

import java.io.*;

class Sample5
{
    public static void main(String[] args) throws IOException
    {
        System.out.println("任務メニュー番号を入力してください。");

        BufferedReader br =
            new BufferedReader(new InputStreamReader(System.in));

        String str = br.readLine();
        int num = Integer.parseInt(str);

        switch(num){
            case 1:
                System.out.println("水の補給メニューを表示します。");
                break;
            case 2:
                System.out.println("携帯食の補給メニューを表示します。");
                break;
            default:
                System.out.println("1か2を入力してください。");
                break;
        }
    }
}

このプログラムでは、入力された値によって表示内容が変わります。

入力値実行される処理
1水の補給メニューを表示します。
2携帯食の補給メニューを表示します。
それ以外1か2を入力してください。

switch(num) によって、num の値を調べています。

switch(num)

num が 1 なら case 1 に進みます。
num が 2 なら case 2 に進みます。
どちらにも一致しなければ default に進みます。

Sample5.javaの処理の流れ

Sample5.java の処理は、次のように進みます。

順番処理内容
1入力をうながすメッセージを表示する
2キーボードから文字列を読み取る
3入力された文字列を整数に変換する
4switch(num) で num の値を調べる
5num が 1 なら case 1 を実行する
6num が 2 なら case 2 を実行する
7どちらにも一致しなければ default を実行する

ここで注目したいのは、case ごとに処理が整理されている点です。

case 1:
    System.out.println("水の補給メニューを表示します。");
    break;

case 1 は、num が 1 のときに実行される場所です。

case 2:
    System.out.println("携帯食の補給メニューを表示します。");
    break;

case 2 は、num が 2 のときに実行される場所です。

default:
    System.out.println("1か2を入力してください。");
    break;

default は、どの case にも一致しなかったときに実行されます。

1を入力した場合

1 を入力した場合、num の値は 1 です。
そのため、case 1 に進みます。

実行例は次のようになります。

任務メニュー番号を入力してください。
1
水の補給メニューを表示します。

この場合、case 1 の処理が実行されます。

System.out.println("水の補給メニューを表示します。");

そのあと、break によって switch文を抜けます。

入力値進む場所表示される内容
1case 1水の補給メニューを表示します。

鬼滅の刃風にたとえると、任務番号 1 は水の補給指令を開く番号です。

2を入力した場合

2 を入力した場合、num の値は 2 です。
そのため、case 2 に進みます。

実行例は次のようになります。

任務メニュー番号を入力してください。
2
携帯食の補給メニューを表示します。

この場合、case 2 の処理が実行されます。

入力値進む場所表示される内容
2case 2携帯食の補給メニューを表示します。

case 2 の処理が終わると、break によって switch文を抜けます。

それ以外を入力した場合

5 を入力した場合、num の値は 5 です。
case 1 にも case 2 にも一致しません。

そのため、default に進みます。

実行例は次のようになります。

任務メニュー番号を入力してください。
5
1か2を入力してください。
入力値進む場所表示される内容
5default1か2を入力してください。

default は、どの case にも一致しなかったときの受け皿です。

鬼滅の刃風にたとえると、任務札の番号が指令表にない場合に、「正しい番号を入力してください」と案内する通常対応です。

if~else if~else文でも同じような処理は書ける

Sample5.java のような処理は、if~else if~else文でも書けます。

if(num == 1){
    System.out.println("水の補給メニューを表示します。");
}
else if(num == 2){
    System.out.println("携帯食の補給メニューを表示します。");
}
else{
    System.out.println("1か2を入力してください。");
}

このように、if~else if~else文でも同じように分岐できます。

ただし、num の値が 1 か 2 か、それ以外か、というように「同じ変数の値」を候補と比べている場合は、switch文 のほうが分岐の一覧が見やすくなることがあります。

書き方特徴
if~else if~else文条件を自由に書ける
switch文同じ式の値ごとの分岐を整理しやすい

score >= 80 のような大小比較には if文 系が向いています。
num が 1、2、3 のどれかを選ぶような場合には switch文 が向いています。

break の役割

switch文を使ううえで、とても大切なのが break です。

break は、switch文の処理をそこで終了し、switch文の外へ抜けるための文です。

Sample5.java では、case 1 の処理のあとに break が書かれています。

case 1:
    System.out.println("水の補給メニューを表示します。");
    break;

この break があることで、case 1 の処理が終わったあと、case 2 や default に進まずに switch文を抜けられます。

役割
case一致した値の処理を始める場所
breakswitch文から抜ける
default一致しなかったときの処理

鬼滅の刃風にたとえると、break は「この指令はここで終了」という合図です。
指令が終わったら次の札へ進まず、switch文の外へ出ます。

break がないとどうなるのか

switch文では、break を書き忘れると、下にある case や default の処理まで続けて実行されることがあります。

たとえば、次のような形です。

switch(num){
    case 1:
        System.out.println("水の補給メニューを表示します。");
    case 2:
        System.out.println("携帯食の補給メニューを表示します。");
    default:
        System.out.println("1か2を入力してください。");
}

このコードには break がありません。

もし num が 1 なら、case 1 に一致します。
そのため、case 1 の処理から始まります。

しかし、break がないため、そこで止まりません。
そのまま下にある case 2 や default の処理まで続けて実行されます。

実行イメージは次のようになります。

任務メニュー番号を入力してください。
1
水の補給メニューを表示します。
携帯食の補給メニューを表示します。
1か2を入力してください。

1 を入力したのに、2 の処理や default の処理まで表示されてしまいます。
これは意図しない動きになりやすいです。

このように、一致した case から下へ処理が続いてしまう動きを、フォールスルーと呼ぶことがあります。

break の位置に注意する

switch文では、break の書き忘れや位置の間違いが、思わぬ動作につながります。

しかも、break の書き忘れはコンパイルエラーにならないことがあります。
そのため、コードを書いたあとに確認することが大切です。

確認すること理由
各 case の最後に break があるか下の case へ続くのを防ぐ
default にも必要なら break があるか処理の終わりを明確にする
どこからどこまで実行されるかフォールスルーを防ぐ
意図的に break を省略していないか読み手に誤解されないようにする

初心者のうちは、まず case ごとに break を書くと安心です。

case 1:
    文;
    break;

この形を基本として覚えておくと、switch文の動きが安定して理解しやすくなります。

数値だけでなく文字でも分岐できる

switch文は、数値だけでなく文字を使った分岐にも使えます。

たとえば、入力された文字が m なら m の処理、n なら n の処理、それ以外なら案内メッセージを表示する、という形です。

ファイル名:Sample6.java

import java.io.*;

class Sample6
{
    public static void main(String[] args) throws IOException
    {
        System.out.println("mかnを入力してください。");

        BufferedReader br =
            new BufferedReader(new InputStreamReader(System.in));

        String str = br.readLine();
        char ch = str.charAt(0);   // 入力された文字列の1文字目を取り出す

        switch(ch){
            case 'm':
                System.out.println("mが入力されました。任務を開始します。");
                break;
            case 'n':
                System.out.println("nが入力されました。任務を中止します。");
                break;
            default:
                System.out.println("mかnを入力してください。");
                break;
        }
    }
}

このプログラムでは、入力された先頭の1文字によって処理を分けています。

入力ch の値実行される処理
m'm'mが入力されました。任務を開始します。
n'n'nが入力されました。任務を中止します。
それ以外その他の文字mかnを入力してください。

switch(ch) によって、文字の値を調べています。

switch(ch)

ch が 'm' なら case 'm' に進みます。
ch が 'n' なら case 'n' に進みます。
どちらでもなければ default に進みます。

Sample6.javaのポイント

Sample6.java で注目したいのは、次の行です。

char ch = str.charAt(0);

readLine で受け取った入力は、まず文字列として扱われます。

たとえば、ユーザーが m と入力しても、str は文字列です。
そこで、charAt(0) を使って、文字列の先頭1文字を取り出しています。

入力strstr.charAt(0)
m"m"'m'
n"n"'n'
menu"menu"'m'

charAt(0) は、文字列の先頭の1文字を取り出すためのメソッドです。

ここでは、詳しい内部構造まで覚える必要はありません。
まずは、文字列から1文字を取り出して char 型の値として使える、ということを押さえておくと大丈夫です。

文字のcaseではシングルクォーテーションを使う

文字で switch文 を書くときは、case の値を char 型の文字として書きます。

case 'm':
case 'n':

ここで使うのは、シングルクォーテーションです。

書き方意味
'm'char 型の1文字
'n'char 型の1文字
"m"文字列
"n"文字列

char 型の1文字は、'm' のようにシングルクォーテーションで囲みます。

文字列は "m" のようにダブルクォーテーションで囲みます。

ここは混同しやすいので注意しましょう。

鬼滅の刃風にたとえると、'm' は「1文字だけの指令印」、"m" は「文字列としての札」です。
switch(ch) で ch が char 型なら、case も 'm' のように char 型で書きます。

図:文字を使ったswitch文の分岐

↓クリックすると拡大表示されます。

この図が示していること

この図では、文字を使って switch文 の分岐ができることを示しています。

入力された文字列から str.charAt(0) で先頭の1文字を取り出し、char 型の ch に入れます。
そのあと、switch(ch) で文字の値を判定します。

ch が 'm' なら、case 'm' の処理を実行します。
ch が 'n' なら、case 'n' の処理を実行します。
どちらにも一致しない場合は default の処理を実行します。

ここから分かることは、switch文は数値だけでなく、char 型の文字でも分岐できるということです。

switch文を使うときのポイント

switch文を使うときは、次の点を意識すると理解しやすくなります。

ポイント内容
1つの式の値で分岐する同じ変数の値ごとに処理を分けやすい
case は一致した値の処理を書く場所一致した case から実行される
default はどれにも一致しないときの処理省略もできる
break が大切書き忘れると下の case まで実行されることがある
文字でも分岐できるchar 型の値を使って分岐できる
文字の case は 'm' のように書くchar 型の1文字はシングルクォーテーションで囲む

特に大切なのは、case と break の関係です。

case は「ここから処理を始める場所」です。
break は「ここで switch文 を抜ける場所」です。

この2つをセットで考えると、switch文の流れが分かりやすくなります。

switch文が向いている場面

switch文は、どんな条件分岐にも使うものではありません。
向いている場面があります。

switch文が向いているのは、同じ対象を複数の決まった値で振り分ける場面です。

向いている場面
メニュー番号ごとの案内1なら飲み物、2なら軽食
曜日番号ごとの表示1なら月曜、2なら火曜
選択文字ごとの処理mなら開始、nなら中止
コード番号ごとの分岐100なら成功、200なら警告
任務番号ごとの指令1なら補給、2なら警戒

一方で、次のような条件には if文 系が向いています。

if文 系が向いている場面理由
score >= 80大小比較だから
age < 20範囲を判定するから
hp <= 0 && item > 0複数条件を組み合わせるから
name.equals("tanaka")値の比較方法が特殊な場合があるから

switch文は、値が決まった候補のどれに一致するかを見たいときに便利です。
範囲や複雑な条件を扱う場合は、if文 系を使うほうが自然です。

switch文を読むときのポイント

switch文を読むときは、次の順番で確認すると分かりやすくなります。

確認すること見る場所
何を基準に分岐しているかswitch の丸かっこの中
どんな候補があるかcase の値
どれにも合わないときdefault
どこで処理が止まるかbreak
意図しない続き実行がないかbreak の有無

たとえば、次のコードを見るときは、

switch(num){
    case 1:
        System.out.println("水の補給メニューを表示します。");
        break;
    case 2:
        System.out.println("携帯食の補給メニューを表示します。");
        break;
    default:
        System.out.println("1か2を入力してください。");
        break;
}

まず switch(num) を見て、num の値で分岐していることを確認します。

次に、case 1 と case 2 を見て、どの値に対応しているかを確認します。

最後に、各 case の終わりに break があるかを見ます。

この順番で読むと、switch文の流れを落ち着いて理解できます。

switch文を理解するための大切な見方

switch文は、if~else if~else文と同じような分岐を、すっきり書ける場合がある便利な構文です。

特に、1つの値をいくつかの候補と比べる場面で使いやすいです。

switch(num)

このように書けば、num の値によって case を選べます。

switch(ch)

このように書けば、ch の文字によって case を選べます。

ただし、switch文では break の扱いがとても重要です。
case に一致したあと、break がないと下の処理まで続いてしまうことがあります。

鬼滅の刃風にたとえると、case は「指令の開始位置」、break は「その指令の終了合図」です。
終了合図がないと、次の指令まで続けて実行してしまいます。

switch文では、次の4つをしっかり押さえておくと安心です。

覚えること内容
switch値による分岐を始める
case一致した値の処理を書く
defaultどれにも一致しないときの処理を書く
breakswitch文から抜ける

この基本が分かると、メニュー選択や文字入力による分岐を、見やすく整理して書けるようになります。