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

2022-09-04 00:47:11

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

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

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

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


答案 1

与往常一样,它在JLS中:

14.11. 声明switch

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

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

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


答案 2

简而言之,这种设计选择符合Java的精神

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

有些人会说这是令人沮丧和不幸的(包括我自己),其他人会虔诚地不同意,坚持认为这是一个“更安全”的决定。

对于另一个令人沮丧的示例,请参阅 enchanced for 循环,如果集合为 ,它也会引发 NPE,而不是表现得好像集合是空的。在 JDK 库中还有更多示例,在这些示例中,调用方必须认真检查所有边缘情况,才能允许它们与“正常”情况统一处理。null

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