最终变量和编译时常量有什么区别?
考虑以下代码
final int a = 5;
final int b;
b=6;
int x=0;
switch(x)
{
case a: //no error
case b: //compiler error
}
这是什么意思?最终变量何时以及如何赋值?运行时会发生什么,编译时会发生什么?为什么我们要给 switch 一个编译时间常数?java的哪些其他结构需要编译时间常数?
最终变量和编译时常量有什么区别?
考虑以下代码
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:
语句在编译时都必须是最终的。你的第一句话是终极的。a
100% 将是5
.
final int a = 5;
但是,对于b
. 如果周围有一个 if 语句b
怎么办?
final int b;
if(something())
b=6;
else
b=5;
这是什么意思?
这意味着“b”不是编译时常量表达式,JLS 要求它是。
最终变量何时以及如何赋值?
形式上,当赋值语句或初始化程序被执行时。
但在实践中,如果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
switch 语句需要一个常量。由于最终变量可以延迟初始化,并且编译器无法确定 b 在 case 分支中有值。
final int b;
可以分配一次并且值不确定,这将根据条件在运行时决定。这就是原因,即使是最终变量,它也不是编译时间常量,尽管它将是一个运行时间常量并且案例需要编译时间常量。