プログラミングを覚えて間もない頃、条件分岐をif文だけに頼ってほぼすべてのプログラミングをif文で作ろうとした記憶ありませんか?それでも出来ないことは無いので個人で使う分には問題無いかもしれません。でもコードの量が増えるにつれ、修正などでそのコードを後に見直す必要が出てきた場合にすごく見難いというか「なにこれ、誰がこんなの作ったの…」となってしまいます。これを俗にスパゲッティコードと呼びますが、こういった緊急事態に陥らないように最初のうちにもう一つの条件分岐も覚えておきましょう。因みにswitch文は人によってswitch-case文という人もいますが言い方が違うだけで中身は一緒です。
基本的な記述ルール
switch文の構文は次のように記述します。
switch(条件) { case 値A: 式が一致した時の処理; break; case 値B: 式が一致した時の処理; break; case 値C: 式が一致した時の処理; break; default: どの値にも属さない場合の処理; }
条件には基となる式を入れます。”case”にはマッチする条件を記述します。条件の終わりには”:”を記述し忘れないように注意してください。
式が一致した時の処理を記述し終えたら最後に”break;”を記述し次のcaseに移行します。
ここで注目してもらいたいのは”default”にはbreakが無いことです。プログラミングの基本的な流れとして上から下の行へ順番にコードを処理するというルールがありますが(カプセル化などをしていない場合の基本的な処理順)、switch文にも当然そのルールは適用されますのでcaseには必ずbreakが必要となります。しかしdefaultはswitch文の最後の行に当たる為breakを付ける必要がありません。
またcaseについては次のように記述することも出来ます。
switch(条件) { case 値A: 値Aの処理; break; case 値B: case 値C: 値B,Cの処理; break; default: どの値にも属さない場合の処理; }
このようにcaseをまとめて記述することも出来ます。
実際に記述してみる
次のコードを見てください。
public static void main(String[] args) throws Exception { int num = 2; switch (num) { case 1: System.out.println("1です。"); break; case 2: System.out.println("2です。"); break; case 3: System.out.println("3です。"); break; default: System.out.println("1でも2でも3でもありません。"); } }
実行結果
2です。
これはint型の変数を宣言しswitch文で分岐処理をする単純なコードであり、実行結果は「2です。」となります。先ほどbreakについての注意を書きましたが、次のコードでは上のコードからbreakを取ってみます。
public static void main(String[] args) throws Exception { int num = 2; switch (num) { case 1: System.out.println("1です。"); case 2: System.out.println("2です。"); case 3: System.out.println("3です。"); default: System.out.println("1でも2でも3でもありません。"); } }
実行結果
2です。 3です。 1でも2でも3でもありません。
このように、breakを取り外すと最初に実行されたcaseより下にある条件が全て無評価で実行されてしまいます。
続いてエラーについてご説明します。
次のコードを見てください。
public static void main(String[] args) throws Exception { int num = 2; switch (num) { case "1": System.out.println("1です。"); break; case "2": System.out.println("2です。"); break; case "3": System.out.println("3です。"); break; default: System.out.println("1でも2でも3でもありません。"); } }
このコードを実行するとコンパイルエラーとなります。これは式と値の型が一致していない為です。このほかにも式または値に”null”がある場合、実行時エラー(NullPointerException)となります。では次にもう一つ見てみましょう。
public static void main(String[] args) throws Exception { int num = 2; switch (num) { case 1: System.out.println("1です。"); break; case 2: System.out.println("2です。"); break; case 3: System.out.println("3です。"); break; case 3: System.out.println("3です。"); break; default: System.out.println("1でも2でも3でもありません。"); } }
switch文ではcaseに重複する値がある場合コンパイルエラーが発生します。よって上のコードの実行結果はエラーとなります。
if文との大きな違いとしてこれらの仕様が挙げられます。条件分岐を重ねていくと人的ミスでエラーが起きやすくなりますが、このようにswitch文を使い分けることで、人的ミスが起こりにくいコードを記述することができるのはswitch文のメリットと言えるでしょう。
便利な使い方
Javaもいよいよ12が実装されましたが、このJava12の実装によりswitch文にも新たな機能が実装されました。
ここではその新機能についてご紹介します。
複数case
次のコードを見てください。
import java.util.Calendar; public class Main { public static void main(String[] args) throws Exception { Calendar calendar = Calendar.getInstance(); int mon = calendar.get(Calendar.MONTH); switch (mon) { case 12,1,2: System.out.println("冬"); break; case 3,4,5: System.out.println("春"); break; case 6,7,8: System.out.println("夏"); break; case 9,10,11: System.out.println("秋"); break; } } }
Java12の実装により、caseに複数の値をセットすることが可能となりました。
以前のVer.でこれを実行すると「multiple case labels are a preview feature and are disabled by default.」となりコンパイルエラーとなっていたので、非常に便利な機能です。
アロー構文
“->”の記号(アロー記号)を利用できるようになりました。この記号を利用することでcaseの後に付くコロンとbreakを省略することが出来るようになります。
記述方法としては以下の通りとなります。
import java.util.*; public class Main { public static void main(String[] args) throws Exception { Calendar calendar = Calendar.getInstance(); int mon = calendar.get(Calendar.MONTH); switch (mon) { case 12,1,2 -> System.out.println("冬"); case 3,4,5 -> System.out.println("春"); case 6,7,8 -> System.out.println("夏"); case 9,10,11 -> System.out.println("秋"); } } }
またブロックを使うことで複数行に渡り処理を行うことも可能です。
記述方法は以下の通りです。
import java.util.*; public class Main { public static void main(String[] args) throws Exception { Calendar calendar = Calendar.getInstance(); int mon = calendar.get(Calendar.MONTH); switch (mon) { case 12,1,2 -> { var txt = "寒い"; System.out.println(txt + "冬"); } case 3,4,5 -> System.out.println("春"); case 6,7,8 -> System.out.println("夏"); case 9,10,11 -> System.out.println("秋"); } } }
まとめ
今回はswitch文について説明しました。
条件分岐という基本的なものにはなりましたが、if文とswitch文の使い分けが明確に分からない方のお役に立てればと思います。
switch文を使うことで、非常にすっきりしたコード作りが出来るようになりますし、何より人的ミスを減らすことにも繋がりますので仕事で複数の開発者がいる場合などには出来る限りスパゲッティコードは避けなくてはなりません。そのためにも基本であるが故に確実にマスターしておきたいものでもあります。
条件に使用できる型には制限があり、その制限は次の通りとなります。
byte型、short型、int型、char型、String型(Java7から)、enum型