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
>
是线程安全的