为什么String switch语句不支持null大小写?
问题内容:
我只是想知道为什么Java 7
switch
语句不支持null
大小写而是抛出NullPointerException
?请参见下面的注释行(示例摘自上的Java教程文章switch
):
{
String month = null;
switch (month) {
case "january":
monthNumber = 1;
break;
case "february":
monthNumber = 2;
break;
case "march":
monthNumber = 3;
break;
//case null:
default:
monthNumber = 0;
break;
}
return monthNumber;
}
这样可以避免if
每次switch
使用前都进行空检查的条件。
问题答案:
正如damryfbfnetsi 在评论中指出的那样,JLS§14.11具有以下注释:
禁止将其
null
用作开关标签,以防止他人编写永远无法执行的代码。如果switch
表达式是引用类型,即String
装箱的原始类型或枚举类型,则如果表达式null
在运行时求值为,则会发生运行时错误。
根据Java编程语言的设计人员的判断,这比静默跳过整个switch
语句或选择在default
标签(如果有的话)之后执行语句(如果有的话)更好。
(强调我的)
虽然最后一句跳过了使用的可能性case null:
,但这似乎是合理的,并提供了语言设计者意图的观点。
如果我们宁愿看一下实现细节,Christian
Hujer的这篇博客文章就为什么null
不允许在开关中进行了一些有见地的推测(尽管它集中在enum
开关而不是String
开关上):
在
switch
后台,该语句通常将编译为一个tableswitch字节码。s
的“物理”论证switch
及其案例int
。通过调用方法确定要打开的int值Enum.ordinal()
。序号从零开始。这意味着映射
null
到0
不是一个好主意。第一个枚举值的开关与null不可区分。从1开始计数枚举的序数也许是个好主意。但是,还没有像这样定义它,因此不能更改此定义。
当String
开关的实现方式不同时,enum
开关首先出现,并为引用类型为引用类型时的行为设定了先例null
。