整数到字节不编译

Vir*_*gaa 6 java byte type-conversion

我有两个几乎相同的程序。第一个编译,第二个不编译。为什么?

我正在将一个int变量分配给一个byte变量。

这个编译:

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

        byte b;
        b = x;

        System.out.println(b);
    }
}
Run Code Online (Sandbox Code Playgroud)

这个不编译:

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

        byte b;
        b = x;

        System.out.println(b);
    }
}
Run Code Online (Sandbox Code Playgroud)

编译器说,不兼容的类型b = x;。但是不应该同样适用于第一个版本吗?

Ste*_*n C 9

这个是晦涩难懂的。真是晦涩难懂。

第一个版本有效,因为 JLS 在第5.2节中说,如果值是常量表达式的结果并且 int 值在 -128 到 +127 的范围内,则您可以intbyte变量赋值。甲常量变量是一个常量表达式,并声明了一个恒定变量final int x = 127;

第二个版本不起作用,因为final int x;没有声明一个常量变量。JLS 在第§4.12.4节中说了以下内容

常量变量是使用常量表达式(第 15.28 节)初始化的原始类型或字符串类型的最终变量。

在第二个版本中,final 变量有一个空白的初始值设定项,然后在稍后分配。结果是第 5.2 节中允许缩小赋值中的原始常量的规则是不允许的。


为什么不能final int x;被视为编译时常量?

考虑一下:

    final int x;
    if (something) {
        x = 127;
    } else {
        x = 1023;
    }
    byte b = x;
Run Code Online (Sandbox Code Playgroud)

应该b允许初始化,还是“有损”转换?这取决于 的值something

假设,编译器可以在上述示例的某些变体中决定所有可能的值x都可以,但是编译器和语言规范中增加的复杂性是不合理的。