2

我在图书馆项目中有一个 Switch 引用来自 R.java 的资源 ID:

switch (code) {

    case R.id.code_one:
        blah();
        break;
    case R.id.code_two:
        bleh();
        break;
}

从 ADT 14 开始,R 字段不再是最终的,因此 Google 建议将 switch 更改为嵌套 if。很公平。

但是,我想知道为什么这不起作用:

final int CODE_ONE=R.id.code_one, CODE_TWO=R.id.code_two;
switch (code) {

    case CODE_ONE:
        blah();
        break;
    case CODE_TWO:
        bleh();
        break;
}

或这个:

class blih {
    private final static int CODE_ONE=R.id.code_one, CODE_TWO=R.id.code_two;
    void bluh(int code) {
        switch (code) {

            case CODE_ONE:
                blah();
                break;
            case CODE_TWO:
                bleh();
                break;
        }
    }
}

他们都抱怨错误“Case statements must be constant expressions”......不是吗,特别是第一个?无论 R.id.xxx 可能是哪个值,我不是将其“最终化”为快照常量吗?

4

2 回答 2

3

Case 语句在编译时必须是常量表达式。如果在运行时初始化它们,它们就不是常量。

final并不意味着“编译时常数”。它仅表示“只能分配一次”。如果最终值已知,这确实使编译器能够在编译时内联值,从而允许final int在 case 表达式中使用初始化的 s。

于 2014-09-09T13:02:09.407 回答
3

它不起作用,因为:

  • switch 语句中的 case 标签必须是编译时常量表达式
  • 您的最终变量CODE_ONE并且CODE_TWO不是编译时常量表达式,因为它们没有使用编译时常量表达式进行初始化。

case 标签是编译时常量表达式的要求:

语言规范中的详细信息

来自 Java 语言规范,第 14.11 节:switch语句

这些标签被称为与 switch 语句相关联,与 case 标签中的常量表达式(第 15.28 节)或枚举常量(第 8.9.1 节)的值一样。

和:

  • 与 switch 语句关联的任何两个 case 常量表达式都不能具有相同的值。

来自 Java 语言规范,第 15.28 节:**常量表达式* *:

15.28。常量表达式...编译时常量表达式是表示原始类型值或字符串的表达式,它不会突然完成并且仅使用以下内容组成:

  • ... [省略其他示例]
  • 引用常量变量(第 4.12.4 节)的简单名称(第 6.5.6.1 节)。
  • TypeName 形式的限定名称(§6.5.6.2)。引用常量变量的标识符(第 4.12.4 节)。

关于常量变量的 JLS ,第 4.12.4 节:final变量

4.12.4 final 变量 ... 原始类型或字符串类型的变量,它是 final 并使用编译时常量表达式(第 15.28 节)初始化,称为常量变量。

于 2014-09-09T13:41:56.683 回答