为什么java switch语句不能处理null,因为它有一个“default”子句?[副本]

t30tvxxf  于 2023-06-28  发布在  Java
关注(0)|答案(4)|浏览(87)

此问题已在此处有答案

Why doesn't String switch statement support a null case?(9个回答)
6年前关闭。
为什么java switch语句不能处理null,因为它有一个“default”子句?
例如,如果您有类似

switch(value){
     case VAL1: do_something1(); break;
     case VAL2: do_something2(); break;
     default: do_something3(); 
   }

“default”不应该处理任何其他值吗,比如null?

piwo6bdm

piwo6bdm1#

像往常一样,它在JLS中:

14.11. switch语句

以下条件必须全部为真,否则会出现编译时错误:

  • ...
  • 没有交换机标签是null

...

  • 禁止使用null作为开关标签,可以防止编写永远无法执行的代码。如果switch表达式是引用类型,即String或装箱基元类型或枚举类型,则如果表达式在运行时计算为null,则会发生运行时错误。根据Java编程语言设计者的判断,这比默默地跳过整个switch语句或选择执行default标签(如果有的话)之后的语句(如果有的话)要好。
clj7thdc

clj7thdc2#

简而言之,这种设计选择符合Java的精神。
当switch表达式的计算结果为null时抛出NPE的决定与Java中的其他决定沿着,它们总是倾向于抛出异常,而不是以“明显”的方式静默处理null。一般的规则似乎是,当有疑问时,Java设计者选择没有默认行为的选项。这样做的副作用是在每个使用站点都需要样板代码。
有些人会说这是令人沮丧和不幸的,但其他人不同意,坚持认为这是一个更安全的决定。
另一个可能令人沮丧的例子是 enchanced for 循环,如果集合是null,它也会抛出NPE,而不是像集合是空的一样。在JDK库中还有更多的例子,调用者必须检查所有边缘情况,才能将它们与“正常”情况统一对待。
作为第三个臭名昭著的例子,Java的检查异常在调用堆栈深度的每一个级别都需要大量的样板来处理,并诱使经验不足的程序员使用几种反模式。结果通常是吞下的异常,同一个异常在日志中被报告了几次,异常在错误的抽象级别上得到了非统一的处理,等等。

z6psavjg

z6psavjg3#

你不能在字符串和其他可以是null的数据类型上使用SWITCH。在Java 7中,这种行为已经改变,允许字符串开关。
请参阅此问题了解更多信息:
Why can't I switch on a String?

enyaitl3

enyaitl34#

这是根据定义。我不会浪费太多时间在这上面,因为它在规格中。
另一方面,我发现这实际上很实用,因为在为null的情况下,它没有关联的原始类型,所以我们不知道如何正确处理它。

相关问题