Java : switch文ではなくswitch式を使おう
switch文を使って break を書き忘れる…意外とあるあるだと思います。
そんなswitch文を改善した、switch式 がJava 14から追加されました。
switch式 を使うことで、break文の書き忘れという単純なミスから解放されます。
本記事では、そんな switch式 の基本的な使い方をご紹介します。
概要
switch式は、Java 14から正式に言語仕様に追加されました。
上記のリンクは、公式ドキュメントによるswitch式の紹介です。一読することをおすすめします。
それではswitch文とswitch式を簡単に見比べてみましょう。
まずは従来のswitch文です。
valueパラメータで条件分岐させて、出力する内容を変えています。
public void main() {
func(1); // いち
func(2); // に
func(3); // さん
func(4); // それ以外
}
public void func(int value) {
switch (value) {
case 1:
System.out.println("いち");
break;
case 2:
System.out.println("に");
break;
case 3:
System.out.println("さん");
break;
default:
System.out.println("それ以外");
}
}
switch の各ケース処理には break文が必要となりますね。
次は switch式です。
public void main() {
func(1); // いち
func(2); // に
func(3); // さん
func(4); // それ以外
}
public void func(int value) {
switch (value) {
case 1 -> {
System.out.println("いち");
}
case 2 -> {
System.out.println("に");
}
case 3 -> {
System.out.println("さん");
}
default -> {
System.out.println("それ以外");
}
}
}
caseラベルの後ろが、コロン ":" の代わりに "->" となります。
各ケースの処理は { ... } というブロックで囲まれます。
// switch文
case 1:
System.out.println("いち");
break;
// switch式
case 1 -> {
System.out.println("いち");
}
ラムダ式を使ったことのあるかたはピンとくるかもしれません。
{ ... } ブロックは if文でも使われていますし、スコープの範囲もより分かりやすく、コードの可読性もよくなったと思います。
そして、switch式では break文は不要となります。
break文の書き忘れが、言語仕様的になくなるわけですね。(すばらしい)
switch式の特徴
{...} ブロック
switch文は、caseラベルから break文までが各ケースの処理の範囲でした。
switch式では break文の代わりに、{ ... } ブロックで処理の範囲(スコープ)を明確にできます。
break文は不要です。
public void main() {
func(1); // いち
func(2); // に
func(3); // さん
func(4); // それ以外
}
public void func(int value) {
switch (value) {
case 1 -> {
System.out.println("いち");
}
case 2 -> {
System.out.println("に");
}
case 3 -> {
System.out.println("さん");
}
default -> {
System.out.println("それ以外");
}
}
}
もしくは、単文の処理であればカッコを省略できます。(もちろんbreakも不要です)
public void func(int value) {
switch (value) {
case 1 -> System.out.println("いち");
case 2 -> System.out.println("に");
case 3 -> System.out.println("さん");
default -> System.out.println("それ以外");
}
}
複数のケースを1つの処理にまとめる
switch文では、意図的にbreak文を省略して複数のケースの処理をまとめる、ということができました。
※switch文の例です。
public void main() {
func(1); // いち、に、さん
func(2); // いち、に、さん
func(3); // いち、に、さん
func(4); // よん
func(5); // ご
func(6); // それ以外
}
public void func(int value) {
switch (value) {
case 1:
case 2:
case 3:
System.out.println("いち、に、さん");
break;
case 4:
System.out.println("よん");
break;
case 5:
System.out.println("ご");
break;
default:
System.out.println("それ以外");
}
}
そんな場合でも大丈夫です。
switch式でも複数ケースをまとめることができます。
public void func(int value) {
switch (value) {
case 1, 2, 3 -> System.out.println("いち、に、さん");
case 4 -> System.out.println("よん");
case 5 -> System.out.println("ご");
default -> System.out.println("それ以外");
}
}
カンマ "," で複数の条件をcaseに指定できます。
式
switch式は、その名のとおり式の特徴を持ちます。
式とは、例えば
i + 2
や
i < 100
などです。
式は結果としての値を持ちます。
その値は代入式で変数に代入できます。
int a = i + 2;
switch式も同じように、代入式の右辺にを置くことができます。
つまり、switch式は値を返すことができます。
public void main() {
func(1); // いち
func(2); // に
func(3); // さん
func(4); // それ以外
}
public void func(int value) {
final String result = switch (value) {
case 1 -> {
yield "いち";
}
case 2 -> {
yield "に";
}
case 3 -> {
yield "さん";
}
default -> {
yield "それ以外";
}
};
System.out.println(result);
}
値を返すには yield キーワードを使います。
もちろん、値を返す switch式で yield を書き忘れるとコンパイルエラーとなります。
書き忘れは発生しません。
もしくはブロックを省略すると、yield も省略できます。
public void func(int value) {
final String result = switch (value) {
case 1 -> "いち";
case 2 -> "に";
case 3 -> "さん";
default -> "それ以外";
};
System.out.println(result);
}
まとめ
switch文と switch式の大きな違いは、break文が必要かどうかです。
break文は、書き忘れという単純なコーディングミスを引き起こしやすい、と個人的には思います。
そんな break文が不要となる switch式は、それだけで有用です。
さらに値も返せて便利です。特にデメリットもありません。
もし Java 14 以降を使っているのあれば、switch文の代わりに switch式 を使うことをおすすめします。
関連記事
- if文の基本
- while文の基本
- for文の基本
- プリミティブ型 (基本データ型)
- リテラルの表記方法いろいろ
- クラスの必要最低限を学ぶ
- インタフェースの default メソッドとは
- インタフェースの static メソッドの使いどころ
- var (型推論) のガイドライン
- アクセス修飾子の基本
- 配列 (Array) の使い方
- 拡張for文 (for-eachループ文)
- try-with-resources文でリソースを自動的に解放
- テキストブロックの基本
- 列挙型 (enum) の基本
- ラムダ式の基本
- レコードクラスの基本 (Record Class)
- メソッド参照の基本
- シールクラスの基本(Sealed Class)
- 無名変数の使い方