为什么这种类型的最终变量初始化不能在 java 中编译?

wht this type of final variable initialization not compile in java?

class Example{
  public static void main(String args[]){   
    final int x=127;

    final int y;
    y=100;

    byte b;

    b=x;
    b=y;
  }
}

考虑将此程序的 x 和 y 变量声明为最终变量。所以我需要把x和y的值赋给b。 b=x;已编译且 b=y;未编译。为什么此代码无法正常工作。请需要解释。

我不知道你想通过这段代码实现什么,但我可能会尝试解释为什么它适用于 x 而不适用于 y。 我可能会拼错严格的命名法,但它是这样的。

一个(可能也是主要的)原因是这个工作和另一个不工作背后的原因是因为编译器如何分析源代码。
final 关键字仅表示该值一旦为 assigned/initialized 就无法更改(并且该值必须在访问之前进行初始化)。

b=x; 赋值有效,因为 x 变量的确切最终值在编译时已知,并且 x 的值是 127,在字节类型范围内。因此它可以分配给 b - x 不会改变,因为它是最终的并且它的值在字节范围内并且在编译时已知。
超出 x 变量(例如 128)的字节范围会产生相同的错误。

b=y; 没有,因为它可能看起来很奇怪,y 变量的最终值在编译时是未知的。编译器不会按照所有指令来评估变量的值。因此,编译器不知道 y 的初始化和声明之间是否有其他指令可能会更改分配给 y 的值。换句话说,分配给 y 的值是在运行时计算的——因为它是另一条指令。

b=y 出现的错误是:

error: incompatible types: possible lossy conversion from int to byte

尝试执行时会产生相同的错误:

int z = 126;
final int zz=z;
b=zz;

或类似这样的内容:

final int zz=new Scanner(System.in).nextInt();
b=zz;

在我的 zz 和你的 y 情况下,变量的最终值在运行时计算,编译器不知道它们的值是否会溢出 [=19= 的范围] 字节。

编译器不是很聪明,或者...是,但没有进行广泛的优化和检查。要求编译器知道 y=100 会使编译时间更长(因为它还需要评估 zz=new Scanner... 表达式)。

它也适用于类似的东西:

final int x=127*2/2;
b=x;

因为 x 的确切值可以在编译时评估。

如果您需要一些规格页面,请告诉我,我稍后可以找。