为什么字符串开关语句不支持空大小写?

2022-08-31 07:55:00

我只是想知道为什么Java 7语句不支持大小写而是抛出?请参阅下面的注释行(示例取自有关 switch 的 Java 教程文章):switchnullNullPointerException

{
    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;
}

这将避免每次使用前进行空检查的情况。ifswitch


答案 1

正如 damryfbfnetsi 在注释中指出的那样JLS §14.11 有以下说明:

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

(强调我的)

虽然最后一句话跳过了使用的可能性,但它似乎是合理的,并提供了语言设计者意图的视图。case null:

如果我们更愿意看一下实现细节,Christian Hujer的这篇博客文章对为什么不允许在开关中使用有一些深刻的猜测(尽管它以开关而不是开关为中心):nullenumString

在后台,该语句通常会编译为表开关字节代码。“物理”参数及其情况是s。要打开的整型值是通过调用方法确定的。[...] 序数从零开始。switchswitchintEnum.ordinal()

这意味着,映射到不是一个好主意。第一个枚举值上的开关与 null 无法区分。也许从1开始计算枚举的序数是个好主意。但是,它还没有被这样定义,这个定义是无法改变的。null0

虽然开关的实现方式不同,但开关首先出现,并为在基准电压为 时打开参考类型的行为树立了先例。Stringenumnull


答案 2

一般来说是令人讨厌的处理;也许一门更好的语言可以没有.nullnull

您的问题可能通过以下方式解决

    switch(month==null?"":month)
    {
        ...
        //case "":
        default: 
            monthNumber = 0;

    }