静态块和静态variables以什么顺序执行?
可能重复:
Java静态类的初始化
为什么stringvariables在初始化块中更新,而不是整数(即使块先写入)
class NewClass { static { System.out.println(NewClass.string+" "+NewClass.integer); } final static String string="static"; final static Integer integer=1; public static void main(String [] args)//throws Exception { } }
我的输出是
static null
PS:还注意到stringvariables初始化发生在块之前,只有当我插入最后修改。 为什么呢?为什么不是整数?我也宣布它是最后的静态
从JLS 第12.4.2节 ,适当地剪断:
初始化C的过程如下:
然后,初始化其值为编译时常量expression式(§8.3.2.1,§9.3.1,§13.4.9,§15.28)的接口的最终类variables和字段。
接下来,按照文本顺序执行类的variables初始值设定项和静态初始值设定项或接口的字段初始值设定项,就好像它们是单个块一样。
所以对于非编译时常量,它不是“所有variables”,然后是“全部静态初始化”,反之亦然 – 它们都是按照文本顺序排列在一起的。 所以如果你有:
static int x = method("x"); static { System.out.println("init 1"); } static int y = method("y"); static { System.out.println("init 2"); } static int method(String name) { System.out.println(name); return 0; }
那么输出将是:
x init 1 y init 2
即使是最终的x
或y
也不会影响这个,因为它们仍然不是编译时常量。
PS:还注意到stringvariables初始化发生在块之前,只有当我插入最后修改。
在这一点上,这是一个编译时常量,基本上内联的任何用法。 此外,如上所述,在初始化器的其余部分之前分配variables值。
JLS的15.28节定义了编译时常量 – 它包含了所有的原始值和String
,而不是包装types,如Integer
。
这里是一个简短而直接的答案给你的问题….
static Variable
:
静态variables是在JVM
加载 Class
时执行的,而当它被实例化或者它的static method
被调用时 , Class
被加载 。
static Block or static Initializer Block
:
静态初始化块在Class
被实例化 之前或者在其static method
被调用之前被初始化, 甚至在它的static variable
被使用之前被初始化。
/////////编辑部分/////////
class NewClass { final static String string = "static"; final static Integer integer = 1; static { System.out.println(NewClas.string + " " + NewClas.integer); } public static void main(String [] args) { // throws Exception new NewClas(); } }
以上将打印 static 1
。
原因是JVM
将执行称为Constant folding
的优化过程 ,对常量variables进行预先计算。
此外,在你的情况下,结果是static null
原因Constant folding
应用于原始types而不是包装对象,在你的情况下它的整数…
它们按给定的顺序(字段和静态块)进行初始化,这就是为什么打印值为null
,没有任何内容被分配给在静态块之后定义的静态字段。