如果你最终移动你的狗实例,你可能会发现输出变成-2
public class Dog {
static final int val1 = -5;// This is final, so will be initialized at compile time
static int val2 = 3;
public int val3;
public static Dog dog = new Dog();//move to here
public Dog() {
val3 = val1 + val2;
}
public static void main(String[] args) {
System.out.println(Dog.dog.val3);//output will be -2
}
}
最后的字段(其值是编译时常量表达式)将首先初始化,然后其余字段将按文本顺序执行。
因此,在你的情况下,当dog实例初始化时,(0)尚未初始化,而(-5)则初始化,因为它是最终的。static int val2
static final int val1
http://docs.oracle.com/javase/specs/jls/se5.0/html/execution.html#12.4.2 指出:
按文本顺序执行类的类变量初始值设定项和静态初始值设定项,或执行接口的字段初始值设定项,就好像它们是单个块一样,除了最终类变量和值为编译时常量的接口的字段首先初始化
更新了较新的文档
这是来自 http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.2 jdk7版本
最终字段位于步骤 6:
然后,初始化最终的类变量和接口的字段,其值为编译时常量表达式
而静态字段位于步骤 9:
接下来,按文本顺序执行类的类变量初始值设定项和静态初始值设定项,或接口的字段初始值设定项,就好像它们是单个块一样。