我知道编译器需要在编译时知道表达式才能编译开关,但为什么 Foo.BA_ 不是常量?
虽然从初始化字段后执行的任何代码的角度来看,它们是常量,但它们不是 JLS 要求的编译时间常量;有关常量表达式1的规范,请参见第 15.28 节常量表达式。这指的是§4.12.4 最终变量,它定义了一个“常量变量”,如下所示:
我们将原始类型或 String 类型的变量称为 final 并使用编译时常量表达式(第 15.28 节)初始化的变量为常量变量。变量是否为常量变量可能对类初始化(§12.4.1)、二进制兼容性(§13.1、§13.4.9)和明确赋值(§16)有影响。
In your example, the Foo.BA* variables do not have initializers, and hence do not qualify as "constant variables". The fix is simple; change the Foo.BA* variable declarations to have initializers that are compile-time constant expressions.
In other examples (where the initializers are already compile-time constant expressions), declaring the variable as final
may be what is needed.
You could change your code to use an enum
rather than int
constants, but that brings another couple of different restrictions:
1 - The constant expression restrictions can be summarized as follows. Constant expressions a) can use primitive types and String
only, b) allow primaries that are literals (apart from null
) and constant variables only, c) allow constant expressions possibly parenthesised as subexpressions, d) allow operators except for assignment operators, ++
, --
or instanceof
, and e) allow type casts to primitive types or String
only.
Note that this doesn't include any form of method or lambda calls, new
, .class
. .length
or array subscripting. Furthermore, any use of array values, enum
values, values of primitive wrapper types, boxing and unboxing are all excluded because of a).