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