Menu

Java の switch 文:case、フォールスルー、アロー構文

Java の switch 文を解説:case ラベル、break とフォールスルー、default 分岐、case のグループ化、モダンなアロー形式、そして switch 式。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

switch は何のためにあるか

switch は 1 つの値を固定された選択肢のリストと比較し、一致した分岐を実行します。同じ変数をさまざまな定数と何度もテストする長い if/else if のチェーンを書いていることに気づいたら、switch は同じことをより明快に表現します。

これはコンパイル時定数との等価チェックしか行いません。範囲をテストしたり条件を組み合わせたりはできません。それらには if/else のままにしましょう。

古典的な switch 文

伝統的な形式は、コロン付きの case ラベルと、各分岐のあとの break を使います。

Java は day を評価し、一致した case へジャンプして、その文を実行し、break で switch を抜けます。default 分岐は他に何も一致しなかったときに実行されます。else のようなものと考えてください。これは省略可能ですが、予期しない値が静かにすり抜けないように、含めておくのが良い習慣です。

break の罠:フォールスルー

これは switch で最もよくあるバグです。break を省くと、実行は一致した case の終わりで止まりません。次の case へとフォールスルーし、break か閉じ括弧に到達するまで実行を続けます。

Level 1 だけを期待するかもしれませんが、これは 3 行すべてを出力します。case 1break がないため、制御はそのまま case 2case 3 へ滑り込みます。本当にフォールスルーが必要なのでない限り、必ず break を付けましょう。そしてフォールスルーに頼るときは、次に読む人が意図的だとわかるようにコメントを残しましょう。

case のグループ化

フォールスルーには 1 つの正当できれいな用途があります。複数の値が 1 つのブロックを共有するように case ラベルを積み重ねることです。ラベルの間にコードを置かず、続けて並べます。

ここでは 'A''B''C' がすべて同じ "Pass" の行を実行します。これが「これらの値のいずれも同じことをする」と表現する意図された方法です。

文字列に対する switch

数値に限られているわけではありません。Java 7 以降、String で switch でき、メニューの選択肢やコマンド名に最適です。

マッチングは大文字・小文字を区別します。"Stop""stop" に一致しないので、入力の大文字・小文字が変わりうるなら、まず正規化してください(たとえば command.toLowerCase())。もう 1 つの落とし穴:commandnull の場合、switch は NullPointerException をスローするので、そこに到達する前に null を防いでください。

モダンなアロー構文

新しい Java(14 以降)は、フォールスルーの罠を設計で解消するアロー形式 case label -> ... を追加しました。各アロー case はちょうど 1 つの分岐を実行し、決してフォールスルーしないので、忘れるべき break はありません。

ラベルを積み重ねる代わりにカンマで値をグループ化していること(case 6, 7)に注目してください。break は 1 つも見当たりません。複数の文にはブロックを使います:case 1 -> { ...; ... }。新しいコードではこの形式を優先しましょう。短く、バグのまるごと 1 クラスを取り除けます。

式としての switch

アロー形式は値を生成することもできます。switch 式は、そのまま変数に代入できる結果を返します。一時変数も、各分岐での繰り返しの代入も不要です。

switch (...) { ... } 全体が、days に格納される数値に評価されます。閉じ括弧のあとのセミコロンに注意してください。これは代入文の一部です。switch 式は網羅的でなければなりません(あらゆる可能な値をカバーする必要があります)。だからここに default があるのです。分岐が値を返す前に複数の文を必要とする場合は、yield を使ったブロックを使います。

case 2 -> {
    boolean leap = (year % 4 == 0);
    yield leap ? 29 : 28;
}

yield は、アローブロックがその値を返す方法であり、結果を運ぶ break の、式の世界における相当物です。

次:for ループ

switch は多くの分岐から 1 つを選びます。ときには、その代わりにブロックを何度も繰り返す必要があります。for ループは、制御された回数だけコードを実行し(範囲を数えたり、各要素をたどったり)、それが次のページです。

よくある質問

Java で if-else ではなく switch を使うべきなのはどんなときですか?

1 つの値を、固定された定数の多数の選択肢と比較するとき、たとえば曜日の番号、メニューの選択肢、enum などと比較するときに switch を使いましょう。長い if/else if のチェーンよりも明快に読め、「これらの既知の値の中から 1 つの分岐を選ぶ」という意図を伝えます。条件が範囲(x > 10)、複数の変数、あるいは定数との単純な等価チェックでない何かを含むときは if/else のままにしましょう。

Java の switch 文ではなぜ break が必要なのですか?

古典的なコロン構文では、ある case が一致すると、break か switch の終わりに到達するまで、実行は後続の case へとフォールスルーします。break はそれを止めます。これを忘れるのは典型的なバグです。case 1: に一致したのに、誤って case 2:case 3: などのコードまで実行してしまうのです。新しいアロー構文(case 1 -> ...)は決してフォールスルーしないので、break はまったく書きません。

Java の switch 文は文字列(String)で動作しますか?

はい。Java 7 以降、String で switch でき、さらに intcharbyteshort、それらのラッパー型、そして enum の値でも switch できます。longdoublefloatboolean では switch できません。文字列のマッチングは大文字・小文字を区別するので、"Yes""yes" は別の case です。

Coddy programming languages illustration

Coddyでコードを学ぼう

始める