Java Initialization块的操作顺序是什么?

时间:2015-07-08 02:35:57

标签: java

我偶然发现了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规范会很棒 - 到目前为止我找不到。

1 个答案:

答案 0 :(得分:1)

我认为这清除了一些事情:

  

没有必要在类定义的开头声明字段,尽管这是最常见的做法。只有在使用它们之前才需要声明和初始化它们。

链接:Oracle Docs

那么显而易见的是,因为你移动了块,Java实际上首先使用默认值初始化变量,打印,分配实际值并再次打印。 这意味着在第一种情况下代码无法执行,因为还没有分配初始值?

我无法解释移动块和时间的关系。所以你的问题实际上仍然是相关的。