我偶然发现了Java中一个奇怪的怪癖,我无法弄清楚为什么这个功能会像它一样。
采用以下示例:
public class InitializerTwo {
{
System.out.println(x);
x = 100;
System.out.println(x);
}
byte x;
public static void main (String[] args) {
InitializerTwo i2 = new InitializerTwo();
System.out.println(i2.x);
}
}
正如预期的那样,初始化块中的两个System.out行失败,因为在定义之前我无法引用字段。
我无法弄清楚为什么赋值(x = 100) 编译,我不明白为什么它不受与System.out相同的定义规则的约束线。我知道类型定义已被考虑因为如果设置x = 1000,我将得到预期的编译错误。
请注意,如果在声明后移动初始化块,代码将按预期编译并生成0,100,100。
任何人都可以解释这种行为吗?链接到官方Java规范会很棒 - 到目前为止我找不到。
答案 0 :(得分:1)
我认为这清除了一些事情:
没有必要在类定义的开头声明字段,尽管这是最常见的做法。只有在使用它们之前才需要声明和初始化它们。
链接:Oracle Docs
那么显而易见的是,因为你移动了块,Java实际上首先使用默认值初始化变量,打印,分配实际值并再次打印。 这意味着在第一种情况下代码无法执行,因为还没有分配初始值?
我无法解释移动块和时间的关系。所以你的问题实际上仍然是相关的。