253
Integer i = ...
    
switch (i) {
    case null:
        doSomething0();
        break;    
}

上記のコードでは、switchcaseステートメントでnullを使用できません。どうすればこれを別の方法で行うことができますか?default何か他のことをしたいので使えません。

4

13 に答える 13

334

switchこれは、Javaのステートメントでは不可能です。nullの前に確認してくださいswitch

if (i == null) {
    doSomething0();
} else {
    switch (i) {
    case 1:
        // ...
        break;
    }
}

switchステートメント*で任意のオブジェクトを使用することはできません。switch (i)コンパイラががどこにiあるかについて文句を言わない理由Integerは、JavaがにIntegerを自動的にアンボックス化するためintです。assyliasがすでに言ったように、開開はwhenisをスローNullPointerExceptioniますnull

*String Java 7以降、switchステートメントで使用できます。

Oracle Docs-Switchの詳細switch(null変数を使用した例を含む)

于 2012-04-26T11:07:11.290 に答える
125
switch ((i != null) ? i : DEFAULT_VALUE) {
        //...
}
于 2015-06-02T16:04:20.823 に答える
45

switch(i)iがの場合、NullPointerExceptionをスローします。nullこれは、をボックスから外そうとするためIntegerですint。したがってcase null、たまたま違法であるが、とにかく到達することはなかったでしょう。

switchステートメントの前に、iがnullでないことを確認する必要があります。

于 2012-04-26T11:06:20.543 に答える
25

Javaドキュメントは次のように明確に述べています。

nullをスイッチラベルとして使用することを禁止すると、実行できないコードを記述できなくなります。スイッチ式がボックス化されたプリミティブ型や列挙型などの参照型である場合、式が実行時にnullと評価されると、実行時エラーが発生します。

Swithchステートメントを実行する前に、nullを確認する必要があります。

if (i == null)

Switchステートメントを参照してください

case null: // will never be executed, therefore disallowed.
于 2012-04-26T11:14:48.647 に答える
15

与えられた:

public enum PersonType {
    COOL_GUY(1),
    JERK(2);

    private final int typeId;
    private PersonType(int typeId) {
        this.typeId = typeId;
    }

    public final int getTypeId() {
        return typeId;
    }

    public static PersonType findByTypeId(int typeId) {
        for (PersonType type : values()) {
            if (type.typeId == typeId) {
                return type;
            }
        }
        return null;
    }
}

私の場合、これは通常、データベース内のルックアップテーブルと一致します(めったに更新されないテーブルの場合のみ)。

ただし、findByTypeIdswitchステートメントで使用しようとすると(おそらく、ユーザー入力から)...

int userInput = 3;
PersonType personType = PersonType.findByTypeId(userInput);
switch(personType) {
case COOL_GUY:
    // Do things only a cool guy would do.
    break;
case JERK:
    // Push back. Don't enable him.
    break;
default:
    // I don't know or care what to do with this mess.
}

...他の人が述べているように、これはNPE@になりswitch(personType) {ます。私が実装を開始した回避策(つまり、「ソリューション」)の1つは、UNKNOWN(-1)型を追加することでした。

public enum PersonType {
    UNKNOWN(-1),
    COOL_GUY(1),
    JERK(2);
    ...
    public static PersonType findByTypeId(int id) {
        ...
        return UNKNOWN;
    }
}

これで、重要な場所でnullチェックを行う必要がなくなり、型を処理するかどうかを選択できますUNKNOWN。(注:-1ビジネスシナリオではありそうもない識別子ですが、明らかにユースケースに適したものを選択してください)。

于 2015-10-02T21:48:45.973 に答える
5

あなたは作る必要があります

if (i == null) {
   doSomething0();
} else {
   switch (i) {
   }
}
于 2012-04-26T11:07:02.430 に答える
4

switch一部のライブラリは、組み込みのjavaステートメントに代わるものを提供しようとします。Vavrはそれらの1つであり、パターンマッチングに一般化されています。

これが彼らのドキュメントからの例です:

String s = Match(i).of(
    Case($(1), "one"),
    Case($(2), "two"),
    Case($(), "?")
);

任意の述語を使用できますが、それらの多くはすぐに使用でき、$(null)完全に合法です。私はこれが他の方法よりも洗練された解決策だと思いますが、これにはjava8とvavrライブラリへの依存が必要です...

于 2016-05-26T12:13:12.767 に答える
3
switch (String.valueOf(value)){
    case "null":
    default: 
}
于 2017-11-30T10:58:12.407 に答える
3

String.valueOf((Object) nullableString) 次のように使用することもできます

switch (String.valueOf((Object) nullableString)) {
case "someCase"
    //...
    break;
...
case "null": // or default:
    //...
        break;
}

興味深いSOQ/ Aを参照してください:String.valueOf(null)がNullPointerExceptionをスローするのはなぜですか

于 2018-05-06T12:00:24.823 に答える
3

@tetsuoの回答に基づいて、java 8を使用:

Integer i = ...

switch (Optional.ofNullable(i).orElse(DEFAULT_VALUE)) {
    case DEFAULT_VALUE:
        doDefault();
        break;    
}
于 2019-12-10T09:59:39.717 に答える
2

できません。スイッチでは、プリミティブ(int、char、short、byte)およびString(java 7の文字列のみ)を使用できます。プリミティブをnullにすることはできません。切り替える前に別の状態で
チェックインしてください。i

于 2012-04-26T11:06:03.323 に答える
1

私は今日、それがnullをチェックしているという理由だけで、インデント/中括弧の別のレイヤーを配置する必要がないことを学びました。次のいずれかを実行できます。

if (i == null) {
    // ...
} else switch (i) {
    case 1:
        // ...
        break;
    default:
        // ...
}

また

if (i != null) switch (i) {
    case 1:
        // ...
        break;
    default:
        // ...
} else {
    // ...
}
于 2021-05-18T04:35:23.753 に答える
0

SWITCHがどのように機能するかを考えてみてください。

  • プリミティブの場合、自動ボクシングのNPEで失敗する可能性があることがわかっています
  • ただし、Stringまたはenumの場合は、equalsメソッドを呼び出している可能性があります。これには、equalsが呼び出されているLHS値が明らかに必要です。したがって、nullでメソッドを呼び出すことができない場合、switchはnullを処理できません。
于 2019-06-18T10:24:57.217 に答える