13

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

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

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

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

4

4 回答 4

13

与往常一样,它在 JLS 中:

14.11。switch声明_

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

  • ...
  • 没有开关标签是null.

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

于 2013-11-12T14:15:39.463 回答
10

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

当 switch 表达式计算结果为时抛出 NPE 的null决定与 Java 中做出的其他决定类似,Java 总是更喜欢抛出异常而不null是以“明显”的方式静默处理。一般规则似乎是,当有疑问时,Java 设计人员会选择导致更多样板代码的选项。

有些人会称这令人沮丧和不幸(包括我自己),而其他人会在宗教上不同意,坚持认为这是一个“更安全”的决定。

对于另一个令人沮丧的示例,请参见增强的 for循环,如果集合是 ,它也会抛出 NPE null,而不是像集合为空一样。JDK 库中还有更多示例,调用者必须认真检查所有边缘情况,以便将它们与“正常”情况一视同仁。

作为第三个臭名昭著的例子,看看检查异常的“语言特性”对你的代码造成的混乱。

于 2013-11-12T14:28:41.190 回答
1

你不能SWITCH对字符串和其他可以是null. Java 7 中已更改此行为以允许字符串切换。

有关更多信息,请参阅此问题:

为什么我不能打开字符串?

于 2013-11-12T14:12:36.853 回答
1

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

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

于 2013-11-12T14:16:25.513 回答