最终变量和编译时常量之间的差异
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分支中具有值。