为什么 java switch 语句不能处理 null,因为它有一个“默认”子句?
例如,如果你有类似的东西
switch(value){
case VAL1: do_something1(); break;
case VAL2: do_something2(); break;
default: do_something3();
}
“默认”不应该处理任何其他值,例如 null 吗?
为什么 java switch 语句不能处理 null,因为它有一个“默认”子句?
例如,如果你有类似的东西
switch(value){
case VAL1: do_something1(); break;
case VAL2: do_something2(); break;
default: do_something3();
}
“默认”不应该处理任何其他值,例如 null 吗?
与往常一样,它在 JLS 中:
14.11。
switch
声明_以下所有条件都必须为真,否则会发生编译时错误:
- ...
- 没有开关标签是
null
....
禁止null
用作开关标签可防止编写永远无法执行的代码。如果 switch 表达式是引用类型,即String
盒装原始类型或枚举类型,则如果表达式在运行时计算为 ,则会发生运行时错误null
。在 Java 编程语言的设计者看来,这比默默地跳过整个switch
语句或选择执行default
标签(如果有)之后的语句(如果有)要好。
简而言之,这种设计选择是本着 Java的精神。
当 switch 表达式计算结果为时抛出 NPE 的null
决定与 Java 中做出的其他决定类似,Java 总是更喜欢抛出异常而不null
是以“明显”的方式静默处理。一般规则似乎是,当有疑问时,Java 设计人员会选择导致更多样板代码的选项。
有些人会称这令人沮丧和不幸(包括我自己),而其他人会在宗教上不同意,坚持认为这是一个“更安全”的决定。
对于另一个令人沮丧的示例,请参见增强的 for循环,如果集合是 ,它也会抛出 NPE null
,而不是像集合为空一样。JDK 库中还有更多示例,调用者必须认真检查所有边缘情况,以便将它们与“正常”情况一视同仁。
作为第三个臭名昭著的例子,看看检查异常的“语言特性”对你的代码造成的混乱。
这是根据定义。我不会在这方面浪费太多时间,因为它在规范中。
另一方面,我发现这实际上非常实用,因为在为 null 的情况下,它没有关联的原始类型,所以我们不知道如何正确处理它。