一.加载

  1. 通过一个类的全限定名获取此类的二进制字节流。
    2. 将二进制字节流所代表的静态存储结构(class文件)转换为方法区的运行时数据结构,这个数据结构存储了类的信息。
    3. 在堆内存中生成一个该类的 Class 对象,作为方法区这些数据的访问入口。

    二.链接

    验证

    验证的目的在于确保Class文件的字节流中包含信息符合当前虚拟机要求,不会危害虚拟机自身安全。
    1. 文件格式验证:验证字节流是否符合Class文件格式规范,例如:是否以魔数0xCAFEBABE开头,主次版本号是否在当前虚拟机处理范围内,常量池中的常量是否有不被支持的类型。
    2. 元数据验证:对字节码描述的信息进行语义分析,以保证其描述的信息符合Java语言规范的要求,例如:这个类是否有父类,是否继承了被final修饰的类,是否重写了父类的final方法。
    3. 字节码验证:通过数据流和控制流分析,确定程序语义是合法的、符合逻辑的,例如:保证任意时刻操作数栈与指令代码序列都能配合工作,跳转指令不会跳到错误的地方。
    4. 符号引用验证:确保解析动作能正确执行,例如:通过符合引用能找到对应的类和方法,符号引用中类、属性、方法的访问性(private,public等)是否能被当前类访问。

    准备

    为类变量(static)分配内存并赋值。没有final修饰的赋0值(0、0L、null、false等),final修饰的赋代码中的值。
    1. private static int a = 10; 在准备阶段值为0
    2. private static final int b = 10; 在准备阶段值为10

    解析

    将常量池内的符号引用替换为直接引用。符号引用就是一组符号来描述目标,比如类名,方法名,字段名。直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。

    三.初始化

    为类的静态变量赋值(代码中的值)。
    执行类构造器 ()方法,()方法在编译过程中生成,此方法中包含了所有类变量的赋值以及静态代码语句块的执行代码,编译器收集的顺序是由执行语句在源文件中的出现顺序来决定的。