28

最终变量和编译时常量有什么区别?

考虑以下代码

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

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

4

5 回答 5

28

问题是,所有case:语句在编译时都必须是最终的。你的第一句话是终极的a100% 将是5.

final int a = 5;

但是,对于b. 如果周围有一个 if 语句b怎么办?

final int b;
if(something())
   b=6;
else
   b=5;
于 2013-03-09T10:52:23.733 回答
7

这是什么意思?

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

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

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

但在实践中,如果final声明了一个编译时常量,则表达式会在编译时进行计算,并且它的值是硬连接到代码中的。

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

往上看。

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

因为 JLS需要它。

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

java的哪些其他结构需要编译时间常数?

没有一个我能想到的,从我的头顶。

于 2013-03-09T10:54:04.703 回答
3

从编译器的角度来看,您正在尝试使用可能未初始化的变量 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
于 2013-03-09T11:00:42.427 回答
2

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

于 2013-03-09T10:34:18.113 回答
2

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

于 2013-03-09T11:02:19.673 回答