public class MyStatic {
private static MyStatic a;
private static MyStatic b;
private String value;
static {
System.out.println("静态代码块初始化中。。。");
a = new MyStatic("a");
System.out.println("静态代码块初始化a完毕");
b = new MyStatic("b");
System.out.println("静态代码块初始化b完毕");
}
{
// new MyStatic();
System.out.println("构造代码块");
}
MyStatic(){
System.out.println("代码块--执行类构造函数");
}
public MyStatic(String value){
System.out.println("构造函数:"+value);
//new MyStatic("a");
}
}
执行结果:
静态代码块初始化中。。。
构造代码块
构造函数:a
静态代码块初始化a完毕
构造代码块
构造函数:b
静态代码块初始化b完毕
构造代码块
构造函数:c
根据Java类的装载流程,Java文件被编译器编译成class字节码文件后,首先是装载:由类装载器装载进入内存中(方法区);随后进入链接阶段:(a)检查:检查载入的class文件数据的正确性 (b)准备:给类的静态变量分配存储空间 (c)解析:将符号引用转成直接引用;最后就是初始化了:对静态变量,静态代码块执行初始化工作。
静态变量的初始化在初始化阶段执行。
所以 private static MyStatic a = new MyStatic("a");
等同于
private static MyStatic a;
static {
a = new MyStatic("a");
}
所以静态代码块在初始化阶段执行优先于构造函数,构造代码块在构造函数之前执行,构造函数被调用一次,构造代码块就执行一次。