类的加载过程可粗略分为三个阶段:加载 -> 链接 -> 初始化
初始化阶段可被8种情况触发:
- 使用 new 关键字实例化对象的时候
- 读取或设置一个类型的静态字段(常量除外)
- 调用一个类型的静态方法
- 使用反射调用类的时候
- 当初始化类的时候,如果发现父类还没有进行过初始化,则先触发其父类初始化
- 虚拟机启动时,会先初始化主类(包含main()方法的那个类)
- 当初次调用 MethodHandle 实例时,初始化该 MethodHandle 指向的方法所在的类。
- 如果接口中定义了默认方法(default 修饰的接口方法),该接口的实现类发生了初始化,则该接口要在其之前被初始化
其中的2,3条目是被static代码触发的。其实初始化阶段就是执行类构造器方法的过程,这个方法是编译器自动生成的,里面收集了static修饰的所有类变量的赋值动作和静态语句块(static{} 块),并且保留这些代码出现的先后顺序。