Javaのプログラムを書くときに、指定した条件に応じて異なる処理を行うことがよくあります。基本的にはif
文を使うこともできますが、複数の条件を扱うときにはswitch
文を使うとコードがすっきりして読みやすくなる場合があります。
switch
文とは、ある値に基づいて異なるコードを実行するための構文です。例えば、曜日を表す数値に応じて「月曜日」「火曜日」といった文字列を表示するようなイメージ。この文を使うと、条件ごとにコードを書く代わりに、まとめてシンプルに書くことができます。
public class SwitchSample { public static void main(String[] args) { int day = 3; // 曜日を表す(1 = 月曜, 2 = 火曜, ...) switch (day) { case 1: System.out.println("月曜日です"); break; case 2: System.out.println("火曜日です"); break; case 3: System.out.println("水曜日です"); break; case 4: System.out.println("木曜日です"); break; case 5: System.out.println("金曜日です"); break; case 6: System.out.println("土曜日です"); break; case 7: System.out.println("日曜日です"); break; default: System.out.println("無効な曜日です"); break; } } } // 出力:水曜日です

このページでは、switch
文の基本的な使い方についてわかりやすくご説明します。
Java:Switch文の基本
switch文は、複数の条件分岐をスマートに書ける構文の1つです。if-else文と同じように条件分岐のために使われますが、大量のif-else if-else...を並べるよりも、読みやすく整理された形で書けるのがメリットです。
例えば、ある変数の値に応じて異なる処理を行いたいときに、以下のように書くと可読性が高くなります。
switch (式) { case 値1: // 値1の場合の処理 break; case 値2: // 値2の場合の処理 break; // 必要に応じてcaseを追加 default: // どの値にも一致しない場合の処理 }
if-elseを多用して書いたのと同じ動作を、コンパクトに表現できるのが特徴です。
switch文の基本1:式
switch
文の最初には、評価される「式」を書きます。式と言っても、基本的には数値や文字列の変数を指定するだけです。ここでの式は、int
、byte
、short
、char
、String
、またはenum
の型を持っている必要(要は、その式を何らかの形で評価できるかどうか)があります。
int day = 3; switch (day) { // ここにcaseラベルと処理を書きます }
switch文の基本2:Caseラベル
次に、case
ラベルを使って、評価された式の値に基づく処理を記述します。各case
の後には、値と、それに対応する処理を書きます。
switch (day) { case 1: System.out.println("Monday"); break; case 2: System.out.println("Tuesday"); break; case 3: System.out.println("Wednesday"); break; // 必要に応じて他のcaseを追加 }

↑変数 day の値に応じて、1の場合は「Monday」を。2の場合は「Tuesday」を。3の場合は「Wednesday」を出力するようにしています。
switch文の基本3:break文
各case
の処理が終わった後には、break
文を書きます。break
文はswitch
文を抜け出すためのものです。つまり、break
にきたらswitch文の処理をやめて次に移るということ。
これを忘れると、次のcase
の処理も実行されてしまう(フォールスルー)ので注意が必要です。
case 1: System.out.println("Monday"); break; // ここでswitch文を抜ける
フォールスルーとは、case
ブロック内にbreak
文を書かずに次のcase
ブロックの処理も続けて実行することです。これを使うと、似たような処理をまとめて書くことができるので、「あえて」フォールスルーを行うこともあります。

以下の例は、day
が1、2、3の場合に「Weekday」と表示されます。このように、複数のcase
が同じ処理を共有する場合にフォールスルーが有効になる場合があります。
int day = 2; switch (day) { case 1: //case 1~2の場合にはbreakしない case 2: case 3: System.out.println("Weekday"); break; case 4: //case 4の場合にもbreakしない case 5: System.out.println("Almost Weekend"); break; case 6: //case 6の場合にもbreakしない case 7: System.out.println("Weekend"); break; default: System.out.println("Invalid day"); }
フォールスルーについてはページ後半でも再度解説します。
switch文の基本4:Defaultラベル
最後に、default
ラベルを使って、どのcase
にも一致しなかった場合の処理を書くというのもポイント。これは必須ではなく任意なのですが、指定しておくと安心です。
int day = 3; switch (day) { case 1: System.out.println("Monday"); break; case 2: System.out.println("Tuesday"); break; case 3: System.out.println("Wednesday"); break; case 4: System.out.println("Thursday"); break; case 5: System.out.println("Friday"); break; case 6: System.out.println("Saturday"); break; case 7: System.out.println("Sunday"); break; default: System.out.println("Invalid day"); }
- 構文:
switch (式) { case 値1: // 処理1; break; case 値2: // 処理2; break; default: // デフォルトの処理; }
- 式:
switch
キーワードの後に評価される式を書く。例:switch (day)
- caseラベル:
- 式の値に基づいて実行されるコードブロックを指定。例:
case 1: // 処理;
- 式の値に基づいて実行されるコードブロックを指定。例:
- break文:
- 各
case
の終了を示し、switch文から抜け出すために使用。例:break;
- 各
- defaultラベル:
- どのcaseラベルにも一致しない場合に実行されるコードブロックを指定。例:
default: // デフォルトの処理;
- どのcaseラベルにも一致しない場合に実行されるコードブロックを指定。例:
- QJavaのswitch式にはなんでlong型は使えないの?
- A
Javaの
switch
式(switch
文を含む)でlong
型が使えない理由は、主に実装のシンプルさとパフォーマンスの観点によるものです。以下のポイントで説明します。1. switch の仕組み
Javaの
switch
は、内部的に以下の2つの方法のどちらかで処理されます。- テーブル・スイッチ(tableswitch)
- ルックアップ・スイッチ(lookupswitch)
これらはバイトコードレベルで
switch
を最適化するための仕組みで、int
やchar
などの整数型が前提となっています。2. long型はメモリ効率が悪い
tableswitch
は、連続した値に対して高速に処理を行うために、ジャンプテーブル(配列のようなもの)を使います。long
型をサポートすると、このテーブルのサイズが大きくなりすぎ、メモリ効率が悪くなります。
3. パフォーマンスの問題
lookupswitch
は、バラバラの値をサポートするために、キーとジャンプ先のアドレスをマップとして管理します。long
型はint
より大きく、比較演算の負荷が増すため、switch
のパフォーマンスが低下します。
4. if-elseで十分対応可能
long
型の値を比較する場合、if-else
文を使えば同じことができます。switch
でlong
をサポートする必要性が薄いため、仕様としてサポートされていません。
switch文とIf文の違い
ここまでswitch文を学んできましたが、実際はどれもif文でも記述できる処理です。じゃ、実際switch文とif文って何が違うの?っていう疑問が浮かぶ方もいるかもしれません。
ので、ここで同じコードをswitch
文とif
文で書くとそれぞれどうなるかを見てみましょう。
サンプル1 Switch文の場合
int day = 3; switch (day) { case 1: System.out.println("Monday"); break; case 2: System.out.println("Tuesday"); break; case 3: System.out.println("Wednesday"); break; case 4: System.out.println("Thursday"); break; case 5: System.out.println("Friday"); break; case 6: System.out.println("Saturday"); break; case 7: System.out.println("Sunday"); break; default: System.out.println("Invalid day"); }
サンプル2 If文の場合
int day = 3; if (day == 1) { System.out.println("Monday"); } else if (day == 2) { System.out.println("Tuesday"); } else if (day == 3) { System.out.println("Wednesday"); } else if (day == 4) { System.out.println("Thursday"); } else if (day == 5) { System.out.println("Friday"); } else if (day == 6) { System.out.println("Saturday"); } else if (day == 7) { System.out.println("Sunday"); } else { System.out.println("Invalid day"); }
ご覧のようにSwitch文の一番のメリットは、コードが見やすくなることです。特に複数の条件を扱う場合、switch文を使うとコードの構造がシンプルでわかりやすくなります。
また数値や文字列の比較において、switch文はif文より実行速度が速い場合があります。利用されるシーンや条件にも応じて変わるのですが、プログラムのパフォーマンスを改善する施策の一環としてif文→switch文にリファクタリングされる場合もあります。

一方で、switch文にはデメリットもあります。
まず、複雑な条件を扱うのには向いていません。複数の条件を組み合わせた複雑な判定を行う場合、switch文では表現しづらいかったりします。また、switch文で使用できるデータ型は限られており、int、byte、short、char、String、enumのみに対応しています。
Switch文の実践的な使い方と注意点
Javaのswitch文は、特定の条件に基づいて異なる処理を実行するのに非常に便利。最後に、現場でよくある使い方と注意点、ベストプラクティスについて説明します。
実践例1 ユーザー権限に応じたメニュー表示
実際の現場では、ユーザーの権限に応じて異なるメニューを表示したいような場合があります。このような場合にswitch文が役立ちます。
public class UserMenu { public static void main(String[] args) { String role = "editor"; // 例としてユーザーの役割を設定 switch (role) { case "admin": System.out.println("管理者メニューを表示します"); // 管理者向けの機能をここに追加 break; case "editor": System.out.println("編集者メニューを表示します"); // 編集者向けの機能をここに追加 break; case "viewer": System.out.println("閲覧者メニューを表示します"); // 閲覧者向けの機能をここに追加 break; default: System.out.println("無効な役割です"); // 無効な役割の場合の処理をここに追加 } } }
実践例2 商品カテゴリに応じた割引計算
商品カテゴリに応じて異なる割引を適用する場合の例です。
public class DiscountCalculator { public static void main(String[] args) { String category = "electronics"; // 商品カテゴリを設定 double price = 100.0; // 商品の価格 double discountPrice; switch (category) { case "electronics": discountPrice = price * 0.9; // 10%の割引 System.out.println("電子機器カテゴリの割引価格: " + discountPrice); break; case "clothing": discountPrice = price * 0.8; // 20%の割引 System.out.println("衣類カテゴリの割引価格: " + discountPrice); break; case "food": discountPrice = price * 0.95; // 5%の割引 System.out.println("食品カテゴリの割引価格: " + discountPrice); break; default: System.out.println("無効なカテゴリです。割引なしの価格: " + price); // 無効なカテゴリの場合の処理をここに追加 } } }
実践編:Switch文を使いこなすためのTips
ここからは実際にJavaの開発者として知っておきたい実践的な知識について補足していきます。
break文とfall-through
Javaのswitch文を使う上で大切な知識が、「break文を使わないと、後続のcaseの処理まで実行される」という特性です。これをフォールスルー (fall-through)と呼びます。※該当する case
から順にすべての case
の処理が実行されます。
サンプルコード break文を省略した場合
public class SwitchFallThrough { public static void main(String[] args) { int day = 2; switch(day) { case 1: System.out.println("月曜日"); case 2: System.out.println("火曜日"); case 3: System.out.println("水曜日"); default: System.out.println("それ以外"); } } }
出力結果はどうなるでしょうか。day = 2
のとき、実行されるのは次の順序です。
case 2:
にマッチする- しかし
break;
が無いため、次のcase 3:
の処理も実行 - さらに
break;
が無いのでdefault:
の処理まで連続して実行
したがって、結果的に
火曜日 水曜日 それ以外
が出力されます。これがJavaのswitch文特有のフォールスルーという動きです。C言語などでも同様の挙動があります。多くの場合は意図せぬ実行を避けるためにbreak;
を書くのが一般的ですが、あえてフォールスルーを活用したい場合もあります。

default
も含めて実行されるという点を頭に入れておきましょう!
フォールスルーを活用する例
複数のケースで処理が同じになる場合、フォールスルーを使うと以下のように書けます。
switch (num) { case 1: case 2: case 3: System.out.println("1か2か3のときの共通処理"); break; default: System.out.println("それ以外のとき"); }
case 1:
にマッチしたらcase 2:
、case 3:
の処理が書いていなくとも「通り抜け」て同じブロックが実行されます。こうすることで、いくつかの値のときに同じ処理をまとめるのが容易になります。
caseは「入口」、breakは「出口」!
switch文のcase
は、それぞれの条件ごとに処理が始まる「入口」というイメージを持つと理解しやすいです。→switch (変数)
の値に合うcase
が見つかると、そこから処理がスタート。必要なところでbreak
(出口)を書いて区切るイメージ。
🔍 switch(値) ├── case 1: ← 入口 (値が1ならここから実行) │ 処理... │ break; ← 出口 (ここで処理終了) │ ├── case 2: ← 入口 (値が2ならここから実行) │ 処理... │ break; ← 出口 │ ├── default: ← どのcaseにも当てはまらなかった時の入口 処理...
int num = 2; switch (num) { case 1: // 入口1 System.out.println("numは1です"); break; // 出口1 case 2: // 入口2 System.out.println("numは2です"); // ここから処理開始 break; // 出口2 case 3: // 入口3 System.out.println("numは3です"); break; // 出口3 default: // どの入口にも合わないとき System.out.println("numは1,2,3以外です"); break; }
case
は、それぞれの値に対応する「入口」。break
を忘れると、次のcase
の処理まで進んでしまう。default
は、どのcase
にも当てはまらないときの「入口」。
switch式 (Java 14以降)
Java 14以降では、switch文の拡張形としてswitch式が正式に追加されました。switch式を使うと、値を返すswitchを書くことができます。また、break
の書き忘れ防止などでコードの安全性・可読性が向上します。
従来のswitch文 (制御構文) とswitch式 (式として値を返すもの)
public class SwitchExpressionExample { public static void main(String[] args) { int num = 2; // switch式 String result = switch (num) { case 1 -> "numは1です。"; case 2 -> "numは2です。"; case 3 -> "numは3です。"; default -> "numは1,2,3以外です。"; }; System.out.println(result); } }
switch (num) { ... }
のあとに ->
を使ってケースごとの「返す値」を直接書いています。
default -> ...
を省略することもできますが、カバーされない値があればコンパイル時警告やエラーになる場合があります。enum
など網羅できる型の場合はdefault -> ...
は省略しても問題ありませんが、基本的にはdefaultは必要である!と覚えておきましょう。
複数の値に対して同じ結果を返す
switch式では、複数のラベルを「,
」区切りでまとめて書けます。次のように書くことで、フォールスルーを使わなくても同じ処理をまとめることができます。
int day = 1; String dayType = switch(day) { case 1, 7 -> "週末"; default -> "平日"; }; // これにより、1(=日曜)と7(=土曜)で同じ処理・結果を返せます。
enumを使ったswitch
Javaには列挙型(enum
)があります。列挙型は定数の集合を表すのに便利です。switch文では、enumの各定数をcase
に指定して分岐が可能です。
public class EnumSwitchExample { // 列挙型を定義 enum Season { SPRING, SUMMER, AUTUMN, WINTER } public static void main(String[] args) { Season current = Season.SPRING; switch(current) { case SPRING: System.out.println("春です"); break; case SUMMER: System.out.println("夏です"); break; case AUTUMN: System.out.println("秋です"); break; case WINTER: System.out.println("冬です"); break; } } }
enum Season { ... }
で列挙型Season
を定義しています。switch
の判定式にSeason
型の変数を指定すると、case
に列挙子(ここではSPRING
,SUMMER
,AUTUMN
,WINTER
)を並べられます。default
節は書かなくてもコンパイルエラーにはなりませんが、網羅性を確保するために書いておく方法もあります(ただし、enumで全列挙子をきちんと書いている場合は必須ではありません)。
列挙型を使うと、判定すべきパターンが増えたり減ったりしにくいことが多く、可読性や安全性の面でもよく利用されます。
ネストされたswitch文
switch文の内部で、さらに別のswitch文を呼び出す「ネスト」した構造を作ることも可能です。ただし、ネストが深くなると可読性が大幅に落ちるため、可能であれば設計・構造を見直すのがおすすめです。
public class NestedSwitchExample { public static void main(String[] args) { int outer = 1; int inner = 2; switch (outer) { case 1: System.out.println("outerは1です"); switch (inner) { case 1: System.out.println("innerは1です"); break; case 2: System.out.println("innerは2です"); break; default: System.out.println("innerは1でも2でもありません"); break; } break; case 2: System.out.println("outerは2です"); break; default: System.out.println("outerは1でも2でもありません"); break; } } }
ネストを多用すると「どこからどこまでがどの分岐なのか」が読み取りづらくなるので、条件分岐のロジックが複雑化しすぎないよう要注意です。大規模な分岐ロジックになりそうな場合は、より適切な設計パターン(多態性、Stateパターンなど)の導入を検討することをおすすめします。