Java 最终变量和编译时常量之间的差异

Java 最终变量和编译时常量之间的差异,java,compile-time-constant,Java,Compile Time Constant,最终变量和编译时常量之间的区别是什么 考虑以下代码 final int a = 5; final int b; b=6; int x=0; switch(x) { case a: //no error case b: //compiler error } 这是什么意思?最终变量何时以及如何赋值?运行时会发生什么,编译时会发生什么?为什么我们要给开关一个编译时常量?java的其他哪些结构需要编译时常量?switch语句需要常量。因为最终变量可以延迟初始化,编译器无法确定b在c

最终变量和编译时常量之间的区别是什么

考虑以下代码

final int a = 5;
final int b;
b=6;
int x=0;
switch(x)
{
     case a: //no error
     case b: //compiler error
}

这是什么意思?最终变量何时以及如何赋值?运行时会发生什么,编译时会发生什么?为什么我们要给开关一个编译时常量?java的其他哪些结构需要编译时常量?

switch语句需要常量。因为最终变量可以延迟初始化,编译器无法确定b在case分支中是否有值

问题是,所有
大小写:
语句在编译时必须是最终的。 你的第一句话是终极的
a
将100%为
5
以外的值

final int a = 5;
但是,对于
b
,不能保证这一点。如果在
b
周围有一个if语句会怎么样

final int b;
if(something())
   b=6;
else
   b=5;
这是什么意思

这意味着“b”不是编译时常量表达式,JLS要求它是

最终变量何时以及如何赋值

正式地,当赋值语句或初始值设定项被执行时

但在实践中,如果
final
声明了编译时常量,则表达式将在编译时求值,其值将硬连接到代码中

运行时会发生什么,编译时会发生什么

见上文

为什么我们要给开关一个编译时常量

因为JLS需要它

字节码编译器必须检查switch语句的格式是否正确;i、 e.开关常数的值不会发生冲突。它还允许JIT编译器生成针对开关常量的实际值进行优化的代码

还有哪些java结构需要编译时常量


从编译器的角度来看,您试图使用一个可能未初始化的变量b。switch语句被编译成JVM字节码表开关或lookupswitch,这要求case语句中使用的值都是编译时常量和唯一值。

final int a = 4; // compiler is sure a is initialized
final int b;// variable b is not guranted to be assigned
e、 g。 虽然此语句最终将初始化b,但编译器无法检测到它

if (a < 4) b= 10;
if (a >= 4) b = 8
如果(a<4)b=10;
如果(a>=4)b=8

最终int b可以分配一次,但值不确定,这将根据条件在运行时决定。这就是原因,即使是一个最终变量,它也不是编译时常量,尽管它将是一个运行时常量,并且case需要编译时常量。

当然,但我仍然没有得到问题的答案。请参阅JLS中指向此主题特定部分的链接