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
语句的其中一种情况下找不到常量时,编译器会抱怨。定义likefinal 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的值仍然依赖于运行时。这是允许的吗?那么我能做些什么呢?