我在图书馆计划中有一个从R.java引用资源ID的Switch:
switch (code) {
case R.id.code_one:
blah();
break;
case R.id.code_two:
bleh();
break;
}
从ADT 14开始,R字段不再是最终字段,因此Google建议将交换机更改为嵌套字段。很公平。
然而,我想知道为什么这不起作用:
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语句必须是常量表达式" ......他们不是,特别是第一个?无论R.id.xxx的值是什么,我都不会最终确定"它变成了快照常量吗?
答案 0 :(得分:2)
在编译时,case语句必须是常量表达式。如果在运行时初始化它们,它们不是常量。
final
并不意味着“编译时常量”。它只表示“只能分配一次”。如果最终值已知,这确实使编译器能够在编译时内联值,允许在case表达式中使用初始化的final int
。
答案 1 :(得分:2)
它不起作用,因为:
CODE_ONE
和CODE_TWO
不是编译时常量表达式,因为它们没有使用编译时常量表达式进行初始化。对case标签的要求是编译时常量表达式:
从Java语言规范section 14.11: The switch
statement:
这些标签据说与switch语句相关联,值也是如此 案例标签中的常量表达式(§15.28)或枚举常量(§8.9.1)。
和:
- 与switch语句关联的两个case常量表达式中没有两个可能具有相同的值。
从Java语言规范section 15.28: **Constant Expressions* *:
15.28。常数表达式 ... 编译时常量表达式是表示基本类型值的表达式或不突然完成的字符串,仅使用以下内容组成:
- ... [其他例子省略]
- 引用常量变量的简单名称(第6.5.6.1节)(§4.12.4)。
- TypeName形式的合格名称(第6.5.6.2节)。引用常量变量的标识符(§4.12.4)。
section 4.12.4: final
Variables
4.12.4最终变量 ... 一个原始类型或类型String的变量,它是final的并用a初始化 编译时常量表达式(第15.28节)称为常量变量。