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

问题描述 投票:0回答:4

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

例如,如果您有类似的东西

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

“默认”不应该处理任何其他值,例如 null?

java switch-statement
4个回答
14
投票

一如既往,在 JLS 中:

14.11。
switch
声明

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

  • ...
  • 无开关标签为
    null

...
禁止使用

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


12
投票

简而言之,这种设计选择是本着Java精神

当 switch 表达式计算结果为

null
时抛出 NPE 的决定与 Java 中做出的其他决定类似,Java 总是更喜欢抛出异常,而不是以“明显”的方式静默处理
null
。一般规则似乎是,当有疑问时,Java 设计者会选择没有默认行为的选项。这具有在每个使用站点都需要样板代码的副作用。

有些人会认为这令人沮丧和不幸,但其他人不同意,认为这是一个更安全的决定。

对于另一个可能令人沮丧的示例,请参阅增强的 for 循环,如果集合是

null
,它也会抛出 NPE,而不是表现得好像集合为空。 JDK 库中还有更多示例,其中调用者必须检查所有边缘情况,以便能够将它们与“正常”情况统一处理。

作为第三个臭名昭著的例子,Java 的检查异常需要大量样板文件来处理调用堆栈深度的每个级别,并引诱经验不足的程序员陷入几种反模式。结果通常是吞掉异常、在日志中多次报告相同的异常、在错误的抽象级别上得到不一致处理的异常等。


1
投票

您不能对字符串和其他可以

SWITCH
的数据类型进行
null
。 Java 7 中已更改此行为以允许字符串切换。

请参阅此问题以获取更多信息:

为什么我无法打开琴弦?


1
投票

这是根据定义。我不会在这方面浪费太多时间,因为它在规范中。

另一方面,我发现这实际上非常实用,因为在为 null 的情况下它没有关联的原始类型,所以我们不知道如何正确处理它。

© www.soinside.com 2019 - 2024. All rights reserved.