Java Switchステートメント
1. 概要
このチュートリアルでは、switchステートメントとは何かとその使用方法を学習します。
switchステートメントを使用すると、ネストされたif-else構造をいくつか置き換えることができるため、コードの可読性が向上します。
Switchは時間の経過とともに進化してきました–特にJava 5および7では、サポートされる新しいタイプが追加されました。 また、進化を続けています。switch式はJava12で導入される可能性があります。
以下に、switchステートメントの使用、breakステートメントの役割、switch引数/case値の要件を示すコード例をいくつか示します。 a switchステートメントのStringsの比較。
例に移りましょう。
2. 使用例
たとえば、次のネストされたif-elseステートメントがあるとします。
public String exampleOfIF(String animal) {
String result;
if (animal.equals("DOG") || animal.equals("CAT")) {
result = "domestic animal";
} else if (animal.equals("TIGER")) {
result = "wild animal";
} else {
result = "unknown animal";
}
return result;
}
上記のコードは見栄えが悪く、保守や推論が難しいでしょう。 読みやすさを向上させるために、ここでswitchステートメントを利用できます。
public String exampleOfSwitch(String animal) {
String result;
switch (animal) {
case "DOG":
result = "domestic animal";
break;
case "CAT":
result = "domestic animal";
break;
case "TIGER":
result = "wild animal";
break;
default:
result = "unknown animal";
break;
}
return result;
}
上に示したように、switch引数animalをいくつかのcase値と比較します。 case値のいずれも引数と等しくない場合、defaultラベルの下のブロックが実行されます。
簡単に言うと、breakステートメントはswitchステートメントを終了するために使用されます。
3. breakステートメント
実際のswitchステートメントのほとんどは、caseブロックの1つだけを実行する必要があることを意味しますが、ブロックの完了後にswitchを終了するには、the breakステートメントが必要です。
breakの記述を忘れると、その下のブロックが実行されます。
これを示すために、breakステートメントを省略し、各ブロックのコンソールに出力を追加しましょう。
public String forgetBreakInSwitch(String animal) {
switch (animal) {
case "DOG":
System.out.println("domestic animal");
default:
System.out.println("unknown animal");
}
}
このコードforgetBreakInSwitch(“DOG”),を実行し、出力をチェックして、すべてのブロックが実行されることを確認しましょう。
domestic animal
unknown animal
したがって、次のラベルの下のコードにパススルーする必要がない限り、注意して各ブロックの最後にbreakステートメントを追加する必要があります。
breakが不要な唯一のブロックは最後のブロックですが、最後のブロックにbreakを追加すると、コードでエラーが発生しにくくなります。
この動作を利用してomit break when we want the same code executed for several case statements.にすることもできます。最初の2つのケースをグループ化して、前のセクションの例を書き直してみましょう。
public String exampleOfSwitch(String animal) {
String result;
switch (animal) {
case "DOG":
case "CAT":
result = "domestic animal";
break;
case "TIGER":
result = "wild animal";
break;
default:
result = "unknown animal";
break;
}
return result;
}
4. switch引数とcase値
次に、switch引数とcase値の許可されるタイプ、それらの要件、およびswitchステートメントが文字列でどのように機能するかについて説明します。
4.1. データ型
switchステートメントですべてのタイプのオブジェクトとプリミティブを比較することはできません。 A switch works only with four primitives and their wrappers, as well as with the enum type and the String class:
-
byteおよびByte
-
shortおよびShort
-
intおよびInteger
-
charおよびCharacter
-
enum
-
ひも
String typeは、Java 7以降のswitchステートメントで使用できます。
enumタイプはJava 5で導入され、それ以降、switchステートメントで使用できるようになりました。
Java 5以降、ラッパークラスも使用可能になりました。
もちろん、switch引数とcase値は同じタイプである必要があります。
4.2. No null Values
We can’t pass the null value as an argument to a switch statement。 これを行うと、プログラムは最初のswitch exampleを使用してNullPointerException,をスローします。
@Test(expected=NullPointerException.class)
public void whenSwitchAgumentIsNull_thenNullPointerException() {
String animal = null;
Assert.assertEquals("domestic animal", s.exampleOfSwitch(animal));
}
もちろん、switchステートメントのcaseラベルに値としてnullを渡すこともできません。 実行すると、コードはコンパイルされません。
4.3. コンパイル時定数としてのCase値
DOGのケース値を変数dog に置き換えようとすると、dog変数をfinalとしてマークするまで、コードはコンパイルされません。
final String dog="DOG";
String cat="CAT";
switch (animal) {
case dog: //compiles
result = "domestic animal";
case cat: //does not compile
result = "feline"
}
4.4. Stringの比較
switchステートメントがequality演算子を使用して文字列を比較した場合、new演算子で作成されたString引数をStringケース値と正しく比較できませんでした。
幸い、switch operator uses the equals() method under the hoodです。
これをデモンストレーションしましょう:
@Test
public void whenCompareStrings_thenByEqual() {
String animal = new String("DOG");
assertEquals("domestic animal", s.exampleOfSwitch(animal));
}
5. 新しいswitch式
Java 12が利用可能であり、それとともに新機能のプレビュー–より冗長でないswitch式。
これを有効にするには、–enable-previewをコンパイラに渡す必要があります。
見てみましょう:
var month = JUN;
var value = switch(month) {
case JAN, JUN, JUL -> 3;
case FEB, SEP, OCT, NOV, DEC -> 1;
case MAR, MAY, APR, AUG -> 2;
};
System.out.println(value); // 3
新しい構文を活用するために、コロンを使用するのではなく、Lambda Expressionsから既知の演算子を使用します。 breakキーワードがないことと、フォールスルーケースが発生していないことに注意してください。
ただし、コードブロックを使用することで、式の右側で何が起こっているかをきめ細かく制御できる可能性があります。 このような場合、手動でbreakを取得し、戻り値を指定する必要があります。
public static void switchLocalVariable() {
var month = Month.AUG;
int i = switch (month){
case JAN,JUN, JUL -> 3;
case FEB,SEP, OCT, NOV, DEC -> 1;
case MAR,MAY, APR, AUG -> {
int j = month.toString().length() * 4;
break j;
}
};
System.out.println(i); //12
}
6. 結論
このチュートリアルでは、Javaでswitchステートメントを使用する際の微妙な点を学びました。 読みやすさと比較された値のタイプに基づいて、switch を使用するかどうかを決定できます。
switchステートメントは、事前に定義されたセット(例:曜日)に限られた数のオプションがある場合に適しています。 そうしないと、新しい値が追加または削除されるたびにコードを変更する必要があり、実行できない可能性があります。 このような場合、polymorphismなどの他のアプローチまたはCommandなどの他のデザインパターンを検討する必要があります。
いつものように、完全なコードはover on GitHubで利用できます。