Integer i = ...
switch (i) {
case null:
doSomething0();
break;
}
上記のコードでは、switchcaseステートメントでnullを使用できません。どうすればこれを別の方法で行うことができますか?default
何か他のことをしたいので使えません。
Integer i = ...
switch (i) {
case null:
doSomething0();
break;
}
上記のコードでは、switchcaseステートメントで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がすでに言ったように、開開はwhenisをスローNullPointerException
しi
ますnull
。
*String
Java 7以降、switch
ステートメントで使用できます。
Oracle Docs-Switchの詳細switch
(null変数を使用した例を含む)
switch ((i != null) ? i : DEFAULT_VALUE) {
//...
}
switch(i)
iがの場合、NullPointerExceptionをスローします。null
これは、をボックスから外そうとするためInteger
ですint
。したがってcase null
、たまたま違法であるが、とにかく到達することはなかったでしょう。
switch
ステートメントの前に、iがnullでないことを確認する必要があります。
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
ビジネスシナリオではありそうもない識別子ですが、明らかにユースケースに適したものを選択してください)。
あなたは作る必要があります
if (i == null) {
doSomething0();
} else {
switch (i) {
}
}
switch
一部のライブラリは、組み込みのjavaステートメントに代わるものを提供しようとします。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;
}
興味深いSOQ/ Aを参照してください:String.valueOf(null)がNullPointerExceptionをスローするのはなぜですか
@tetsuoの回答に基づいて、java 8を使用:
Integer i = ...
switch (Optional.ofNullable(i).orElse(DEFAULT_VALUE)) {
case DEFAULT_VALUE:
doDefault();
break;
}
できません。スイッチでは、プリミティブ(int、char、short、byte)およびString(java 7の文字列のみ)を使用できます。プリミティブをnullにすることはできません。切り替える前に別の状態で
チェックインしてください。i
私は今日、それがnullをチェックしているという理由だけで、インデント/中括弧の別のレイヤーを配置する必要がないことを学びました。次のいずれかを実行できます。
if (i == null) {
// ...
} else switch (i) {
case 1:
// ...
break;
default:
// ...
}
また
if (i != null) switch (i) {
case 1:
// ...
break;
default:
// ...
} else {
// ...
}
SWITCHがどのように機能するかを考えてみてください。