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 ((i != null) ? i : DEFAULT_VALUE) {
//...
}
switch(i)
如果 i 是null
,则会抛出 NullPointerException ,因为它会尝试将 拆箱Integer
为int
。因此case null
,碰巧是非法的 ,无论如何都不会达到。
您需要在switch
语句之前检查 i 是否为空。
Java 文档明确指出:
禁止使用 null 作为开关标签可以防止编写永远无法执行的代码。如果 switch 表达式是引用类型,例如装箱的原始类型或枚举,则如果表达式在运行时计算为 null,则会发生运行时错误。
在执行Swithch 语句之前,您必须验证是否为空。
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) {
。我开始实施的一个变通方法(即“解决方案”)是添加一个UNKNOWN(-1)
类型。
public enum PersonType {
UNKNOWN(-1),
COOL_GUY(1),
JERK(2);
...
public static PersonType findByTypeId(int id) {
...
return UNKNOWN;
}
}
现在,您不必在重要的地方进行空值检查,您可以选择是否处理UNKNOWN
类型。(注意:-1
在业务场景中不太可能是标识符,但显然选择对您的用例有意义的东西)。
你必须做一个
if (i == null) {
doSomething0();
} else {
switch (i) {
}
}
一些库试图提供内置 javaswitch
语句的替代方案。Vavr就是其中之一,他们将其概括为模式匹配。
这是他们文档中的一个例子:
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:Why does String.valueOf(null) throw a NullPointerException
switch (String.valueOf(value)){
case "null":
default:
}
基于@tetsuo 的回答,使用 java 8 :
Integer i = ...
switch (Optional.ofNullable(i).orElse(DEFAULT_VALUE)) {
case DEFAULT_VALUE:
doDefault();
break;
}
你不能。您可以在 switch 中使用原语(int、char、short、byte)和字符串(仅限 java 7 中的字符串)。原语不能为空。切换前在单独的条件下
检查i
。
只要考虑一下 SWITCH 可能如何工作,
我今天刚刚了解到,您不必仅仅因为检查空值的 if 就再放一层缩进/大括号。您可以执行以下任一操作:
if (i == null) {
// ...
} else switch (i) {
case 1:
// ...
break;
default:
// ...
}
或者
if (i != null) switch (i) {
case 1:
// ...
break;
default:
// ...
} else {
// ...
}
这
switch
对于 Java 中的语句是不可能的。检查null
之前switch
:if (i == null) { doSomething0(); } else { switch (i) { case 1: // ... break; } }
您不能在
switch
语句* 中使用任意对象。编译器不抱怨switch (i)
wherei
is anInteger
的原因是因为 Java 自动将 the 拆箱Integer
为 anint
。正如 assylias 已经说过的,拆箱会抛出一个NullPointerException
wheni
isnull
。*从 Java 7 开始,您可以
String
在switch
语句中使用。Oracle Docs 中的更多信息
switch
(包括带有空变量的示例)- Switch