1.加载
装载类的第一个阶段
取得类的二进制流
转为方法区数据结构
在 Java 堆中生成对应的 java.lang.Class 对象
2.链接
1)验证
保证 Class 流的格式是正确的
• 文件 格式的验证
是否以 0xCAFEBABE 开头
版本号是否合理
• 元数据验证
是否有父类
继承了 final 类?
非抽象类实现了所有的抽象方法
• 字节 码验证 ( 很复杂 )
运行检查
栈数据类型和操作码数据参数吻合
跳 转指令指定到合理的位置
2)准备
分配内存,并为类设置初始值 (方法区中)
public static int v=1;
在准备阶段中, v 会被设置为 0
在初始化的 < clinit > 中才会被设置为 1
对于 static final 类型,在准备阶段就会被赋上正确的值
public static final int v=1;
3)解析
符号引用替换为直接引用
3.初始化
执行类构造器<clinit>
static 变量 赋值语句
static{} 语句
子 类的 < clinit > 调用前保证父类的 < clinit > 被调用
< clinit > 是线程安全的