我有两个几乎相同的程序。第一个编译,第二个不编译。为什么?
我正在分配一个 int
变量到 byte
多变的。
这个编译:
class Example {
public static void main(String args[]) {
final int x = 127; // directly initialized
byte b;
b = x;
System.out.println(b);
}
}
这个不编译:
class Example {
public static void main(String args[]) {
final int x;
x = 127; // assigned later
byte b;
b = x;
System.out.println(b);
}
}
编译器在
b = x;
说不兼容的类型.但是不应该同样适用于第一个版本吗?
最佳答案
这个是晦涩难懂的。真是晦涩难懂。
第一个版本有效,因为 JLS 在 §5.2 部分说您可以分配一个 int
值到 byte
如果值是常量表达式的结果并且 int 值在 -128 到 +127 的范围内,则变量。常量变量是一个常量表达式,而 final int x = 127;
声明一个常量变量。
第二个版本不起作用,因为 final int x;
不声明常量变量。 JLS 在 §4.12.4 部分说了以下内容:
A constant variable is a final variable of primitive type or type String that is initialized with a constant expression (§15.28).
在第二个版本中,final 变量有一个空白的初始值设定项,然后在稍后分配。结果是第 5.2 节中允许缩小赋值中的原始常量的规则是不允许的。
为什么不能
final int x;
被视为编译时常量?考虑一下:
final int x;
if (something) {
x = 127;
} else {
x = 1023;
}
byte b = x;
应该初始化
b
被允许,还是会是一个“有损”的转换?这取决于 something
的值.假设,编译器可以在上述示例的某些变体中决定
x
的所有可能值。没问题,但是编译器和语言规范中增加的复杂性是不合理的。
关于java - 整数到字节不编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59911569/