Java switch语句中的最终变量大小写 final int a=1; 最终int b; b=2; 最终整数x=0; 开关(x){ 案例a:break;//好的 案例b:break;//编译器错误:需要常量表达式 } /*编译器结果: 需要常量表达式 案例b:断裂; ^ 1错误 */

Java switch语句中的最终变量大小写 final int a=1; 最终int b; b=2; 最终整数x=0; 开关(x){ 案例a:break;//好的 案例b:break;//编译器错误:需要常量表达式 } /*编译器结果: 需要常量表达式 案例b:断裂; ^ 1错误 */,java,switch-statement,case,final,Java,Switch Statement,Case,Final,为什么我会犯这样的错误?如果我完成了final int b=2,一切都正常。b可能尚未初始化,可能会被分配多个值。在您的示例中,它显然已初始化,但编译器可能不知道这一点(它也不能)。想象一下: final int b; if (something) { b = 1; } else { b = 2; } 编译器在开关中需要一个常量,但b的值取决于某个外部变量。没有赋值的最终变量称为空白变量。空白决赛只能分配一次,并且必须在分配发生时或在程序中分配一次时取消分配 为了做到这一点,Jav

为什么我会犯这样的错误?如果我完成了
final int b=2
,一切都正常。

b
可能尚未初始化,可能会被分配多个值。在您的示例中,它显然已初始化,但编译器可能不知道这一点(它也不能)。想象一下:

final int b;
if (something) {
   b = 1;
} else {
   b = 2;
}

编译器在
开关中需要一个常量,但
b的值取决于某个外部变量。

没有赋值的最终变量称为空白变量。空白决赛只能分配一次,并且必须在分配发生时或在程序中分配一次时取消分配

为了做到这一点,Java编译器运行一个流分析,以确保对于一个空白的最终变量的每个赋值,在赋值之前该变量肯定是未赋值的;否则会发生编译时错误


这就是为什么编译器编译switch构造时抛出必需的常量表达式,因为编译器不知道b的值。

switch语句中的大小写应该是编译时的常量。命令

final int b=2
在编译时将
2
的值赋给
b
。但是下面的命令在运行时将
2
的值分配给
b

final int b;
b = 2;

因此,当编译器在
switch
语句的其中一种情况下找不到常量时,编译器会抱怨。

定义like
final int b
将使其成为变量。因此,在初始化它之前,它有空值,最后初始化,为什么这个开关表达式不接受变量?Roman,你在说什么?:)@RomanC你确定你的评论正确吗?只是问一下。但编译器“看不到”我在下一行(声明之后)初始化了它,所以它不应该担心它在其他地方初始化了吗?@Furlando不,编译器不能这样做。想象一下,在创建
final int a=1后,使用一个复杂的方法从数据库或其他外部源检索值,而不是使用这个
if
子句。@Furlando
并像
x=3*a*a
那样使用它,编译器将优化您的代码,并在字节码中将
a
替换为
1
,这就是为什么您可以在
案例a:break中使用它b
可以在以后像
final int a=new Random()那样声明。nextInt()
编译器无法预测
b
将是什么,也无法用
case
参数所需的某个常量替换它,这就是为什么您会看到错误的原因。是的,但我认为两者是一样的。后者不能编译的时间,因为编译器是不确定的:)@ BoZo,为了解释差异,考虑一下:最终INTB=什么?1 : 2; 因此,b的值仍然依赖于运行时。这是允许的吗?那么我能做些什么呢?