最终变量和编译时常数之间有什么区别?
考虑以下代码
final int a = 5;
final int b;
b=6;
int x=0;
switch(x)
{
case a: //no error
case b: //compiler error
}
这是什么意思?何时以及如何为最终变量赋值?运行时会发生什么以及编译时会发生什么?我们为什么要给switch一个编译时常量? java的其他结构需要编译时间常量吗?
答案 0 :(得分:26)
问题是,所有case:
语句在编译时必须是最终的。
您的第一个声明是终极。 a
100%的价值不会超过5
。
final int a = 5;
但是,对于b
,无法保证。如果在b
周围有if语句怎么办?
final int b;
if(something())
b=6;
else
b=5;
答案 1 :(得分:7)
这是什么意思?
这意味着'b'不是编译时常量表达式,而JLS要求它是。
何时以及如何为最终变量赋值?
正式执行赋值语句或初始值设定项时。
但实际上,如果final
声明了编译时常量,则表达式在编译时进行计算,并将其值硬连接到代码中。
运行时会发生什么以及编译时会发生什么?
见上文。
为什么要给switch一个编译时常量?
因为JLS 需要它。
字节码编译器必须检查switch语句是否格式正确;即,开关常数的值不会发生冲突。它还允许JIT编译器生成针对开关常量的实际值进行优化的代码。
java的其他结构需要编译时间常量吗?
我无法想到的,无论如何。
答案 2 :(得分:3)
从编译器的角度来看,您尝试使用的变量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
答案 3 :(得分:2)
switch语句需要一个常量。由于最终变量可以被延迟初始化,并且编译器无法确定b它在case分支中具有值。
答案 4 :(得分:2)
final int b;
可以分配一次且值不确定,将根据条件决定运行时。这就是原因,即使是最终变量,它也不是 COMPILE TIME 常数,尽管它将是 RUN TIME 常量和案例需求编译时间常数。