Integer i = ...
switch (i) {
case null:
doSomething0();
break;
}
在上面的代码中,我不能在switch case语句中使用null。我该怎么做呢?我不能用默认,因为我想做别的。
Integer i = ...
switch (i) {
case null:
doSomething0();
break;
}
在上面的代码中,我不能在switch case语句中使用null。我该怎么做呢?我不能用默认,因为我想做别的。
当前回答
一些库尝试提供内置java switch语句的替代方案。Vavr就是其中之一,他们把它推广到模式匹配。
以下是他们文档中的一个例子:
String s = Match(i).of(
Case($(1), "one"),
Case($(2), "two"),
Case($(), "?")
);
您可以使用任何谓词,但它们提供了许多开箱即用的谓词,$(null)是完全合法的。我发现这是一个比替代方案更优雅的解决方案,但这需要java8和对vavr库的依赖…
其他回答
Java文档明确指出:
禁止使用null作为开关标签可以防止编写永远不能执行的代码。如果开关表达式是引用类型,例如盒装基元类型或enum,如果表达式在运行时求值为空,则会发生运行时错误。
在switch语句执行之前,必须验证是否为空。
if (i == null)
参见Switch语句
case null: // will never be executed, therefore disallowed.
switch ((i != null) ? i : DEFAULT_VALUE) {
//...
}
基于@tetsuo的答案,java 8:
Integer i = ...
switch (Optional.ofNullable(i).orElse(DEFAULT_VALUE)) {
case DEFAULT_VALUE:
doDefault();
break;
}
这在Java 18之前是不可能用switch语句实现的。在切换之前必须检查是否为空。但是现在,有了模式匹配,这些都成为过去式了。看看JEP 420:
模式匹配和空 传统上,switch语句和表达式会抛出 如果选择器表达式的结果为null,则为NullPointerException null测试必须在开关外部完成:
static void testFooBar(String s) {
if (s == null) {
System.out.println("oops!");
return;
}
switch (s) {
case "Foo", "Bar" -> System.out.println("Great");
default -> System.out.println("Ok");
}
}
当switch只支持少数参考类型时,这是合理的。 然而,if switch允许任何类型的选择器表达式和大小写 标签可以有类型模式,这样独立的空测试才有感觉 就像一个武断的区分,并引起不必要的样板文件和 犯错的机会。最好是集成空测试 进入开关:
static void testFooBar(String s) {
switch (s) {
case null -> System.out.println("Oops");
case "Foo", "Bar" -> System.out.println("Great");
default -> System.out.println("Ok");
}
}
更多关于开关(包括空变量的例子)在Oracle Docs - switch
一些库尝试提供内置java switch语句的替代方案。Vavr就是其中之一,他们把它推广到模式匹配。
以下是他们文档中的一个例子:
String s = Match(i).of(
Case($(1), "one"),
Case($(2), "two"),
Case($(), "?")
);
您可以使用任何谓词,但它们提供了许多开箱即用的谓词,$(null)是完全合法的。我发现这是一个比替代方案更优雅的解决方案,但这需要java8和对vavr库的依赖…