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

时间:2013-03-09 10:31:11

标签: java compile-time-constant

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

考虑以下代码

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

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

5 个答案:

答案 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 常量和案例需求编译时间常数。