Integer i = ...
switch (i){
case null:
doSomething0();
break;
}
上記のコードでは、switch case文にnullを使用できません。これを別の方法で行うことができますか? default
は使用できません。それ以外のことをしたいのです。
これは、Javaのswitch
ステートメントでは不可能です。 null
の前にswitch
を確認します。
if (i == null) {
doSomething0();
} else {
switch (i) {
case 1:
// ...
break;
}
}
switch
ステートメントで任意のオブジェクトを使用することはできません*。 i
がInteger
であるswitch (i)
についてコンパイラが文句を言わないのは、JavaがInteger
をint
に自動アンボックス化するためです。アサイラスがすでに言ったように、NullPointerException
がi
の場合、ボックス化解除はnull
をスローします。
* Java 7以降では、String
ステートメントでswitch
を使用できます。
のswitch
(null変数の例を含む)についての詳細は、Oracle Docs - Switch を参照してください。
switch ((i != null) ? i : DEFAULT_VALUE) {
//...
}
iがnull
である場合、switch(i)
はNullPointerExceptionをスローします。これは、Integer
をint
にアンボックス化しようとするためです。そのため、case null
(これは違法であることが起こります)は、とにかく決して到達されなかったでしょう。
switch
ステートメントの前に、iがNULLではないことを確認する必要があります。
Javaのドキュメントは明確にこう述べています。
スイッチラベルとしてnullを使用しないことで、決して実行できないコードを書くことを防ぐことができます。 switch式がボックス型プリミティブ型やenumなどの参照型の場合、式が実行時にnullと評価されると実行時エラーが発生します。
Swithchステートメントを実行する前に、nullを確認する必要があります。
if (i == null)
switch文 を参照してください。
case null: // will never be executed, therefore disallowed.
与えられた:
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;
}
}
私にとっては、これは通常、データベース内のルックアップテーブルと一致します(めったに更新されないテーブルのみ)。
しかし、findByTypeId
をswitch文で使用しようとすると(ほとんどの場合、ユーザー入力から)...
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
はビジネスシナリオでは考えられない識別子ですが、明らかにあなたのユースケースに意味のあるものを選択してください)。
あなたがする必要があります
if (i == null) {
doSomething0();
} else {
switch (i) {
}
}
いくつかのライブラリは組み込みのJava switch
ステートメントに代わるものを提供しようとします。 Vavr はそのうちの1つで、パターンマッチングに一般化します。
これは 彼らのドキュメント からの例です:
String s = Match(i).of(
Case($(1), "one"),
Case($(2), "two"),
Case($(), "?")
);
あなたはどんな述語も使うことができます、しかしそれらは箱から出してそれらの多くを提供します、そして$(null)
は完全に合法です。私はこれが他のものよりももっと洗練された解決策であると思います、しかしこれはJava8とvavrライブラリへの依存を必要とします...
switch (String.valueOf(value)){
case "null":
default:
}
String.valueOf((Object) nullableString)
を使うこともできます
switch (String.valueOf((Object) nullableString)) {
case "someCase"
//...
break;
...
case "null": // or default:
//...
break;
}
面白いSOを参照してくださいQ/A: String.valueOf(null)がNullPointerExceptionをスローするのはなぜですか
SWITCHがどのように機能するかを考えてください。
できません。スイッチにはプリミティブ(int、char、short、byte)とString(Java 7のStringsのみ)を使用できます。プリミティブはnullにできません。
切り替えの前にi
を別の状態で確認してください。