Integer i = ...
switch (i){
case null:
doSomething0();
break;
}
上記のコードでは、switch caseステートメントでnullを使用できません。どうすればこれを別の方法で実行できますか?他のことdefault
をしたいので使えません。
Integer i = ...
switch (i){
case null:
doSomething0();
break;
}
上記のコードでは、switch caseステートメントでnullを使用できません。どうすればこれを別の方法で実行できますか?他のことdefault
をしたいので使えません。
回答:
これはswitch
、Javaのステートメントでは不可能です。のnull
前に確認してくださいswitch
:
if (i == null) {
doSomething0();
} else {
switch (i) {
case 1:
// ...
break;
}
}
switch
ステートメントで任意のオブジェクトを使用することはできません*。コンパイラがswitch (i)
どこにi
あるかについて文句を言わない理由Integer
は、Javaがへの自動アンボックスInteger
を行うためint
です。assyliasは、すでに述べたように、アンボクシングがスローされますNullPointerException
ときi
ですnull
。
* Java 7以降String
、switch
ステートメントで使用できます。
Oracle Docsの詳細switch
(null変数の例を含む)-スイッチ
null
場合、これは妥当なケースではありません。おそらく、実装は舞台裏での呼び出しに依存しますが(それでも、「序数」が-1として扱われるのはなぜですか?)、バージョンはポインタ比較を使用して何かを行います(または、厳密に逆参照が必要なものに依存します)オブジェクト)?String
enum
enum
ordinal()
null
String
intern()
Javaのドキュメントでは、次のように明確に述べられています。
スイッチラベルとしてnullを使用することの禁止により、実行できないコードを作成できなくなります。スイッチ式がボックス化されたプリミティブ型や列挙型などの参照型である場合、式が実行時に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
ビジネスシナリオではありそうもない識別子ですが、明らかにユースケースに適したものを選択してください)。
UNKNOWN
これは私がこれまでに見た中で最高の解決策であり、nullchecksを克服します。
一部のライブラリは、組み込みのjava switch
ステートメントに代わるものを提供しようとします。Vavrはその1つであり、パターンマッチングに一般化されています。
String s = Match(i).of(
Case($(1), "one"),
Case($(2), "two"),
Case($(), "?")
);
任意の述語を使用できますが、それらの多くはそのまま使用でき、$(null)
完全に合法です。これは他の方法よりもエレガントな解決策ですが、これにはjava8とvavrライブラリへの依存関係が必要です...
次のString.valueOf((Object) nullableString)
ように使用することもできます
switch (String.valueOf((Object) nullableString)) {
case "someCase"
//...
break;
...
case "null": // or default:
//...
break;
}
興味深いSO Q / Aをご覧ください:String.valueOf(null)がNullPointerExceptionをスローする理由
できません。プリミティブ(int、char、short、byte)とString(Java 7の文字列のみ)をスイッチで使用できます。プリミティブをnullにすることはできません。スイッチの前に別の状態で
チェックi
してください。