多くの条件を含むコードを作成するとき、if-elseステートメントまたはswitchステートメントを使用したことがあるはずです。しかし、このif-elseの代替には欠点があります。switchステートメントを「アンチパターン」と呼ぶ人もいます。

あれは何でしょう?アンチパターンは、悪いコード、つまり問題に対する不適切な解決策の一般的なパターンです。これらはコードの品質を低下させるため、プログラマはコード内でそれらを避けようとします。

しかし良いニュースもあります。Java の新しいバージョンでは、言語の構文に多くの変更が加えられており、それらの変更の 1 つがswitchに影響を与えます。興味をそそられましたか? それでは、潜ってみましょう。

まず、switch がアンチパターンである理由を明確にする価値があります。次のコードを考えてみましょう。


switch (condition) {
    case "DECEMBER":
        seasonNumber = 1;
        break;
    case "JANUARY":
        seasonNumber = 1;
        break;
    case "FEBRUARY":
        seasonNumber = 1;
        break;
    default:
        seasonNumber = 0;
}

さて、なぜこれが「アンチパターン」なのかはまだ完全には明らかではありません。

しかし、さらにcaseブロックを追加して、コードが次のようになった場合はどうなるでしょうか。


switch (condition) {
    case "DECEMBER":
        seasonNumber = 1;
        break;
    case "JANUARY":
        seasonNumber = 1;
        break;
    case "FEBRUARY":
        seasonNumber = 1;
        break;
    case “MARCH”:
        seasonNumber = 2;
        break;
    case “APRIL”:
        seasonNumber = 2;
        break;
    case “MAY”:
        seasonNumber = 2;
        break;
    default:
        seasonNumber = 0;
}

さらに数行追加しましょう。コードは長くなります。後からさらに行を追加することもできますが、これを止める人は誰もいません。

これが問題の核心です。最初にコンパクトなswitchステートメントを作成した後、それにコードを追加すると、画面に収まりきらないほど多くのスペースが占有され、コードの読み取りと保守が不便になってしまいます。

switch文とswitch式の違い

Java 14 では、新しく改良されたスイッチが導入されました。これはswitch ステートメントではなく、switch 式です。

違いは何ですか?違いは、ステートメントは特定の一連の操作を実行する命令であるのに対し、式は何らかの計算を実行して結果を返すコードの一部であるという点です。

つまり、スイッチの結果を変数に保存できるようになりました。

話はもう十分です。新しいスイッチがどのようなものかを見てみましょう。


var result = switch(month) {
     case DECEMBER, JANUARY, FEBRUARY -> 1;
     case MARCH, APRIL, MAY -> 2;
    case JUNE, JULY, AUGUST -> 3;
    case SEPTEMBER, OCTOBER, NOVEMBER -> 4;
    default -> 0; 
};

最初に目を引くのは、コードがいかにコンパクトであるかということです。以前は画面の大部分を占めていたコードが数行に広がり、はるかに読みやすくなりました。

-> 演算子

->演算子 (矢印演算子)にも注意してください。ラムダ式の経験がある場合は、すでによく知っているかもしれません。

つまり、ラムダ ステートメントのスタイルで見栄えの良いスイッチを作成できるようになりました。矢印演算子は、コンパイラーが次のcase式に進まず(現在のcaseブロックにbreakまたはreturnステートメントがない場合)、代わりに矢印の右側にある式の値を与えることを示します。

式ではなく、何も返さずに単に特定のアクションを実行するコードを作成することもできます。


switch(condition) {
    case TRUE, FALSE -> System.out.println("True/false");
  
    default -> System.out.println("Another");
}

switch にはBreakステートメントがなくなったことに注意してください。これは Java 13 で削除され、yieldに置き換えられました。

利回りとは何ですか? どこで使用できますか?

スイッチが1 行で構成されている場合、 ->演算子自体が値を返します。しかし、コード行が 1 行ではなく、多数ある場合はどうなるでしょうか? このような場合、行は 1 つではなく複数あるため、矢印演算子は値を返しません。

return を使ってもいいでしょうか?結局のところ、これは Java で値を返すために使用されます。残念ながら、スイッチでは戻ることはできません。では、何が使えるのでしょうか?以前はBreakがありましたが、Java 13 では削除されました。しかし、その代わりに、スイッチから値を返すのに役立つ新しいキーワードであるyield が追加されました。これは、メソッド内のreturnステートメントに似ています。


var result = switch(condition) {
//…
case "Hi" -> "greeting"
//…
};  

このコードには 1 行が含まれており、->演算子は「挨拶」を返します。

しかし、コードのブロックがある場合:


var result = switch(condition) {
//…
case "Hi" -> {
// Your code
 Here you need to return "greeting"
	}
};  

値を返すのに役立つキーワードはyieldです。


var result = switch(condition) {
//…
case "Hi" -> {
// Your code
 yield "greeting";

	}
};

yield は、 case ブロック内に複数行のコードがあり、結果を返す必要がある場合に備えて Java 13 に追加されました。

コード内で新しいスイッチを試してみたいと思っているかもしれませんが、これを行うには Java 14 以降が必要であることに注意してください。以前のバージョンでは、このスイッチは、コマンド ラインで「--enable-preview」フラグを指定した場合にのみ使用できます。バージョン 14 より前は、言語の本格的な部分ではなく、テクニカル プレビューの一部であったためです。

それは今のところすべてです!またね!