Java『switch文の書き方』値によって処理を分岐する|if文との使い分け

Java≫switch文の書き方≫値によって処理を分岐する_if文との使い分けJavaプログラミング入門

【本サイトではGoogleアドセンス、または、アフィリエイト広告を利用しています。】

switch文の書き方

switch文とは、if文と同じように条件に従って処理を切り替える構文です。

考え方はif文と同じですが、指定できる条件としては、
変数が値と一致するかどうかのみです。

じゃあ、if文の方が優秀だし、switch文なんて使わなくていいんじゃないの?

 自慢する人

そ、それも一理あります。

if文では複雑な条件を指定できますし、メンテナンス性も高いので、
実際そのような考えでプログラムを書く人もいます。

でも、それはswitch文のことを理解してから判断しても遅くはありません!

使いどころによっては、switch文の方が読みやすく、
整理しやすいこともある
のです。

この辺りについては後程サンプルコードを見ながらお話します。

まずは、switch文の書き方です。

switch (式) {
  case 値1:
    処理1;
    break;
  case 値2:
    処理2;
    break;
  case 値3:
    処理3;
    break;
  …
  default:
    処理N;
    break;
}

プログラムで例を書くと以下のような感じです。
変数aはint型で、テストの点数を入れるとします。

switch (a) {
	case 0:
		System.out.println("0点!なんてこった!");
		break;
	case 100:
		System.out.println("100点!すごいぜ!");
		break;
	default:
		System.out.println("よく頑張った!");
		break;
}

まず、switchの後ろに書く式についてですが、
式というよりは、ある値が入る変数を条件として書くものと考えてください。

次に、各条件に一致する処理をcase文としてそれぞれ書いていきます。
条件としては、式として書いた変数に入る値を指定します。
条件の最後には「:」半角のコロンをつけます。

また、各処理の最後には「break;」文を書きます。
これは、各処理を切り分けて動作させる為に必要となります。
もし書かなかった場合どのような動きになるかについては後述します。

そして、どの条件にも当てはまらない時のパターンとして、defaultを指定します。
これは、if文のelseと同様の使い方で、指定しなくても動くので、
必要であれば書きましょう。

switch文の基本的な考え方や書き方については、以下でも説明していますので、
あわせて読んでいただくとより理解が深まると思います。

switch文の使い方|サンプルコード

書き方を覚えたところで、
switch文を使ったサンプルコードを見ていきましょう!

if文の時と同じく、のび太くんがテストをママに見せた時の反応を作ってみました。

package example;

public class Example {
	public static void main(String[] args) {

		// テストの点数
		int result = 0;

		switch (result) {
			// 0点の時
			case 0:
				System.out.println("のーびー太ぁぁぁぁーーー!");
				break;
			// 100点の時
			case 100:
				System.out.println("まあ!のびちゃまー!");
				break;
			// 上記以外の時
			default:
				System.out.println("がんばったわね!");
				break;
		}
	}
}

このまま実行すると結果はこのような感じになります。

のーびー太ぁぁぁぁーーー!

はい、0点なので怒られました!
のび太くんにとっては通常運転です。

プログラムの動きを説明すると、resultの値が0なので、
0という値に一致するcase文の処理が実行されたことになります。

では、これからドラえもんになって、タイムマシーンに乗りましょう!
resultの値をいろいろ変えて、のび太くんを助けてあげてください!

break文がないとどうなるか?

case文の中に書く各処理の最後には、break文を書くのがお決まり事になっています。

しかし、Javaでは、break文を書かなくても実行することができます

では、breakを書かないとどうなるのか?
先ほどのサンプルコードのbreak文をすべて消して実行してみましょう!

package example;

public class Example {
	public static void main(String[] args) {

		// テストの点数
		int result = 0;

		switch (result) {
			// 0点の時
			case 0:
				System.out.println("のーびー太ぁぁぁぁーーー!");
				// 100点の時
			case 100:
				System.out.println("まあ!のびちゃまー!");
				// 上記以外の時
			default:
				System.out.println("がんばったわね!");
		}
	}
}

実行結果は以下です。

のーびー太ぁぁぁぁーーー!
まあ!のびちゃまー!
がんばったわね!

こ、これは、すべてのcase処理が実行されてしまいました

のび太くんも対応に困ると思います。
きっと、次のセリフは「ドラえも~ん!」になることでしょう。

なぜこんなことが起こったのか?プログラムの動きを説明します。

まず、プログラムは上から下に順番通り実行されていきます。

プログラムの実行がswitch文に到達した時のresultの値は「0」なので、
値「0」に一致するcase文、つまり「0点の時」の処理に入ります。

「0点の時」の処理を見てみると、
System.outの出力処理があるので実行されます。

さて、ここからが重要です。

 分かれ道に立つ人

出力処理が終わった後、プログラムとしては、
次の行にある「case 100:」のコードが評価されます。

この場合、resultは「0」なので、本来は処理を飛ばされそうですが、
switch文の性質上、次のcase文の中も実行されてしまう
のです。

この性質は、フォールスルーと呼ばれます。

フォールスルーとは、一度case文の条件に一致すると、
それより後の処理は条件に関わらずすべて実行するという性質
のことです。

なので、「case 100:」も「default:」も
すべて実行された結果が返ってきたのです。

では、フォールスルーをさらに検証する為に、
サンプルコードをもう少しいじってみましょう。

package example;

public class Example {
	public static void main(String[] args) {

		// テストの点数
		int result = 100;

		switch (result) {
			// 0点の時
			case 0:
				System.out.println("のーびー太ぁぁぁぁーーー!");
				// 100点の時
			case 100:
				System.out.println("まあ!のびちゃまー!");
				// 上記以外の時
			default:
				System.out.println("がんばったわね!");
		}
	}
}

resultの値を100にしてみました。これで実行してみます。

まあ!のびちゃまー!
がんばったわね!

「case 100:」以降の処理がフォールスルーされてすべて実行されましたね!

このように、break文を書き忘れたりすると、
本来実行されてはいけないコードが実行されてしまう可能性もある
ので、

switch文を書く時は、基本的にbreak文を書くクセをつけておきましょう!

switch文で複数条件を指定する方法

と、ここで、フォールスルーについて理解できたところで、さらに応用編です。

switch文で複数条件の指定はできないのか?

という疑問についてです。

if文のような複雑な条件指定はできませんが、以下であれば可能です。

値1、または、値2、または、…値Nに一致する時

これには、フォールスルーの性質を利用します
以下のサンプルコードを見てください。変数aはint型とします。

switch (a) {
	case 0:
		System.out.println("0点!なんてこった!");
		break;
	case 100:
		System.out.println("100点!すごいぜ!");
		break;
	case 98:
	case 99:
		System.out.println("おしい!");
		break;
	default:
		System.out.println("よく頑張った!");
		break;
}

テストの点数が98点、または、99点のパターンを追加しました。

この場合、98点に一致しても、フォールスルーの性質が働いて、
break文が出てくるまでコードは実行されていくので、
そのまま99点のcaseに書かれた処理が実行されます。

つまり、上記のようにcase文を続けて書くことで、
「または」と同じ動きを実行させることができる
わけです。

使い方を誤ると、意図しないコードが実行されてしまうので、
しっかり頭の中でパターンを整理して使うようにしてください。

switch文とif文との違いは?どっちを使うべきか?

次は、条件分岐における最大の疑問、switch文とif文の違いについてです。

 賢いプログラム

ここまでにご紹介したサンプルコードは、すべてif文で書き換えることができます。
つまり、switch文は使わなくともプログラムは書けてしまいます。

また、if文に比べると、メンテナンス性に欠ける
break文の書き忘れによって、フォールスルーが意図せず動くなど
使うリスクもやや大きいです。

なので、switch文を使うところは、if文よりも限定的になってきます。

プログラマーの考え、プロジェクト全体の思想によって変わるので、
正解というものは特にないですが、

以下の考え方で使い分けるのは1つの手として有効です。

【if文の使いどころ】
・複雑な条件式が必要
・1つの値ではなく、ある程度の範囲によって処理が変わるような場合

【switch文の使いどころ】
・条件式が値に一致するかどうかという単純なものである
・変数に入る値のパターンが決まっている

まさに、名前の通り、ON/OFFの切り替えなど、
スイッチとして機能させたい処理には、switch文で書くのが最適です。

例えば、画面の表示モードで処理を切り分ける場合、
何かのステータスで処理を切り分ける場合
などです。

また、その場合、プログラムもswitch文で書いた方が見やすくなります

ということで、switchが必要となる状況でなければ、
基本的にはif~elseを使うようにしましょう

switch式とは?switch文との違いは?特徴と使い方

ここ最近、新たにswitch式というものが登場してきました。

switch「文」とは違います。switch「式」です。
特徴や違いとしては、以下です。

  • break文は不要。(フォールスルーの性質を持たない。)
  • カンマ区切りで1つのcase文に複数の値を指定できる。
  • 単文処理の場合は、ブロック({}で囲む書き方)を省略できる。
  • yield文で結果を返すことができる。

条件分岐の考え方としてはswitch文と全く同じですが、
全体的に使い勝手が良くなりました

break文の指定忘れもこれでなくなります。

サンプルは以下です。先ほど説明したコードと同じ動きをします。
caseの指定には、「:」ではなく「->」を使います

String message;
int result = 0;

switch (result) {
    case 0 -> {
        message = "0点!なんてこった!";
    }
    case 100 -> {
        message = "100点!すごいぜ!";
    }
    case 98,99 -> {
        message = "おしい!";
    }
    default -> {
        message = "よく頑張った!";
    }
}

System.out.println(message);

case文の中の処理が単文なので、ブロックを省略するとこんな感じになります。

String message;
int result = 0;

switch (result) {
	case 0 -> message = "0点!なんてこった!";
	case 100 -> message = "100点!すごいぜ!";
	case 98, 99 -> message = "おしい!";
	default -> message = "よく頑張った!";
}

System.out.println(message);

yield文と呼ばれるコードを使って、
値を返すようにすると
、こういった書き方もできます。

変数messageの中に直接switch文を入れ込んでyieldで値を返しています。

int result = 0;

String message = switch (result) {
	case 0 -> {
		yield "0点!なんてこった!";
	}
	case 100 -> {
		yield "100点!すごいぜ!";
	}
	case 98, 99 -> {
		yield "おしい!";
	}
	default -> {
		yield "よく頑張った!";
	}
};

System.out.println(message);

ブロックを省略すると、yield文も同時に省略できるので、
出力処理の中にswitch式を入れ込んで、返す値を変数に入れずに
そのまま出力するプログラムにすると、ここまでコードが省略できます。

int result = 0;

System.out.println(switch (result) {
	case 0 -> "0点!なんてこった!";
	case 100 -> "100点!すごいぜ!";
	case 98, 99 -> "おしい!";
	default -> "よく頑張った!";
});

どうでしょう?すっきりしましたね。

注意点として、switch式はここ最近出てきた文法なので、
Javaのバージョンによっては使えないことと、

そもそもこの構文を使える人が少ないこと、

この辺りも踏まえて、使うかどうかは判断してください。

まとめ

switch文の使い方について以下説明しました。

  • switch文の書き方
  • break文がない時の動き(フォールスルー)
  • switch文で複数条件を指定する方法
  • switch文とif文の違いと使い分け
  • switch式の特徴と使い方

また、最後に紹介したswitch式について、

Javaを今から始める人は、まだここまで理解できなくて大丈夫です。
最初にご紹介したswitch文をまずは使えるようになりましょう!

次回は、for文の書き方について説明します!

タイトルとURLをコピーしました