为什么 String switch 语句不支持 null 情况?
我只是想知道为什么 Java 7 switch
语句不支持 null
情况而是抛出 NullPointerException
?请参阅下面的注释行(示例取自 关于 的 Java 教程文章切换
):
I am just wondering why the Java 7 switch
statement does not support a null
case and instead throws NullPointerException
? See the commented line below (example taken from the Java Tutorials article on 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;
}
这将避免在每次 switch
使用之前进行空检查的 if
条件.
This would have avoided an if
condition for null check before every switch
use.
推荐答案
作为damryfbfnetsi 在评论中指出,JLS §14.11 有以下注释:
As damryfbfnetsi points out in the comments, JLS §14.11 has the following note:
禁止使用 null
作为开关标签可以防止编写永远无法执行的代码.如果 switch
表达式是引用类型,即 String
或装箱的原始类型或枚举类型,则如果表达式求值,则会发生运行时错误null
在运行时.在 Java 编程语言的设计者看来,这比默默地跳过整个 switch
语句或选择执行 default 之后的语句(如果有)更好的结果
标签(如果有).
The prohibition against using
null
as a switch label prevents one from writing code that can never be executed. If theswitch
expression is of a reference type, that is,String
or a boxed primitive type or an enum type, then a run-time error will occur if the expression evaluates tonull
at run time. In the judgment of the designers of the Java programming language, this is a better outcome than silently skipping the entireswitch
statement or choosing to execute the statements (if any) after thedefault
label (if any).
(强调我的)
虽然最后一句跳过了使用 case null:
的可能性,但它似乎是合理的,并提供了对语言设计者意图的看法.
While the last sentence skips over the possibility of using case null:
, it seems reasonable and offers a view into the language designers' intentions.
如果我们更愿意看一下实现细节,这篇博文Christian Hujer 对为什么在开关中不允许使用 null
有一些有见地的推测(尽管它以 enum
开关而不是 String
开关为中心):
If we rather look at implementation details, this blog post by Christian Hujer has some insightful speculation about why null
isn't allowed in switches (although it centers on the enum
switch rather than the String
switch):
在底层,switch
语句通常会编译为tablesswitch 字节码.而物理"switch
的参数及其案例是 int
s.要打开的 int 值是通过调用方法 Enum.ordinal()
确定的.[...] 序数从零开始.
Under the hood, the
switch
statement will typically compile to a tablesswitch byte code. And the "physical" argument toswitch
as well as its cases areint
s. The int value to switch on is determined by invoking the methodEnum.ordinal()
. The [...] ordinals start at zero.
这意味着,将 null
映射到 0
并不是一个好主意.第一个枚举值的开关与 null 没有区别.也许从 1 开始计算枚举的序数是个好主意.但是它并没有这样定义,而且这个定义不能更改.
That means, mapping null
to 0
wouldn't be a good idea. A switch on the first enum value would be indistinguishible from null. Maybe it would've been a good idea to start counting the ordinals for enums at 1. However it hasn't been defined like that, and this definition can not be changed.
虽然 String
开关 实现方式不同,但 enum
switch 最先出现,并开创了在引用为 null
时打开引用类型的行为方式的先例.
While String
switches are implemented differently, the enum
switch came first and set the precedent for how switching on a reference type should behave when the reference is null
.
相关文章