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

final变量和编译时常量之间有什么区别?

请考虑以下代码

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

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

问题是, 所有case:语句必须在编译时是最终的 。 你的第一个声明是终极的 。 100% a遗嘱不是5以外的其他价值。

 final int a = 5; 

但是, b 不保证这一点。 如果b周围会有if语句怎么办?

 final int b; if(something()) b=6; else b=5; 

这是什么意思?

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

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

forms上,当执行赋值语句或初始化程序时。

但实际上,如果final声明了编译时常量,则表达式在编译时进行计算,并将其值硬连接到代码中。

运行时会发生什么以及编译时会发生什么?

往上看。

我们为什么要给switch一个编译时常量?

因为JLS 需要它。

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

java的其他结构需要编译时间常量?

没有我能想到的,在我的头脑中。

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

 final int a = 4; // compiler is sure a is initialized final int b;// variable b is not guranted to be assigned 

虽然这个语句最终会初始化b,但编译器无法检测到它。

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

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

switch语句需要一个常量。 由于最终变量可以被延迟初始化,并且编译器无法确定b它在case分支中具有值。