Javaスイッチステートメント

1概要

このチュートリアルでは、 switch ステートメントの意味と使い方について学びます。

switch ステートメントを使うと、入れ子になったいくつかの if-else 構文を置き換えることができ、コードの読みやすさが向上します。

Switch は時間とともに進化してきました - 特にサポートされる新しい型がJava 5と7で追加されました。また、進化し続けています - switch 式はおそらくJava 12で導入されるでしょう。

以下に、 switch ステートメントの使用、 break ステートメントの役割、 switch 引数/ case 値の要件、および a switch ステートメント内の __String __の比較を示すコード例をいくつか示します。

例に移りましょう。

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 を終了するには 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 を追加するとコードのエラーが少なくなります。

複数のcaseステートメントに対して同じコードを実行する場合は、この動作を利用して break を省略することもできます。** 最初の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 ステートメントがStringsとどのように機能するかについて説明しましょう。

4.1. データ型

switch ステートメントのすべての種類のオブジェクトとプリミティブを比較することはできません。 switch は、4つのプリミティブとそれらのラッパー、および __enum型 String__クラスでのみ機能します。

  • バイト バイト

  • ショート ショート

  • int Integer

  • char Character

  • enum

  • String

__String typeは、Java 7以降の switch__ステートメントで使用可能です。

enum typeはJava 5で導入され、それ以来 switch ステートメントで利用可能です。

ラッパークラスもJava 5以降で利用可能です。

もちろん、 switch 引数と case 値は同じ型である必要があります。

4.2. NULL値なし

  • null 値を switch ステートメントの引数として渡すことはできません** 。

そうすると、プログラムは最初の __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 case値を変数 __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 ステートメントが等価演算子を使用して文字列を比較した場合、 String 引数を String case値と正しく比較できませんでした。

幸い、 switch 演算子は、フードの下で__equals()メソッドを使用しています

これを実証しましょう。

@Test
public void whenCompareStrings__thenByEqual() {
    String animal = new String("DOG");
    assertEquals("domestic animal", s.exampleOfSwitch(animal));
}

5新しい スイッチ ステートメント

Java 12のスケジュール では、 exampleOfSwitch() メソッドで行ったように、 break ステートメントを記述して result 値を返す必要はありません新しい case ラベルと switch 式へ。

新しい " case L - > "ラベルでは、矢印ラベルの右側のブロックだけが実行され、その下のブロックは実行されません。

新しい switch 式を使用して、 switch 全体を result 変数に割り当て、値を矢印ラベルの右側に直接配置できます。これはKotlin/Scalaのような他の言語がすでに持っている便利な機能です。

また、 case ブロック内のローカル変数の有効範囲は、 switch ブロック全体ではなく、この case ブロックになります。

これは最終リリースまで変更される可能性があることに注意してください。

6. 結論

このチュートリアルでは、Javaで switch ステートメントを使用することの微妙な点について学びました。読みやすさと比較する値の種類に基づいて、 __ switch __を使用するかどうかを決定できます。

switch文は、事前に定義されたセット内に限られた数のオプションがある場合(例:曜日)に適した候補です。

それ以外の場合は、新しい値が追加または削除されるたびにコードを変更する必要がありますが、現実的ではない可能性があります。このような場合は、https://www.baeldung.com/java-polymorphism[polymorphism]などの他のデザインパターン、またはhttps://www.baeldung.com/java-command-pattern[Command]のような他のデザインパターンを検討する必要があります。 。

いつものように完全なコードが利用可能ですhttps://github.com/eugenp/tutorials/tree/master/core-java-lang-syntax[GitHubで動く]