九又四分之三站台

0%

类的加载过程

Java虚拟机中类加载的过程分为五步:加载,验证,准备,解析,初始化。

加载

“加载”是“类加载”过程的一个阶段,在这个阶段,虚拟机需要完成以下三件事

  1. 通过一个类的全限定名来获取定义此类的二进制字节流
  2. 把这个字节流所代表的静态存储结构转化为方法区运行时的数据结构
  3. 在内存中生成代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口

验证

验证是连接阶段的第一步,目的是为了确保Class文件中字节流中的信息符合当前虚拟机的要求

  1. 文件格式验证:验证字节流是否符合Class文件格式规范,并且是否能被当前虚拟机处理
  2. 元数据验证: 对字节码描述的信息进行语义分析,保证信息能符合Java语言规范的要求
  3. 字节码验证: 通过数据里和控制流分析,保证程序语义是合法的

准备

准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些变量使用的内存都将在方法区中分配。 主要要进行内存分配的是类变量(被static修饰的变量)而不包括实例变量,并且这里所说的初始值是指数据类型的零值

1
public static int value = 123;

在准备阶段后value的初始值的0而不是123,把value赋值为123在初始化阶段才会进行。

通常情况下准备阶段初始值是零值,但是还会有其它情况在准备阶段会直接赋值

1
public static final int value = 123;

在value被final修饰以后,编译时Javac会为value生成ConstantValue属性,在准备阶段虚拟机就会根据ConstantValue的设置将value赋值为123。

解析

解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程

符号引用
符号引用是以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可。 符号引用和虚拟机实现的内存布局无关,引用的目标并不一定已经加载到内存中。

直接引用
直接引用是可以直接指向目标的指针,相对偏移量或者是一个能直接定位到目标的句柄。直接引用是和虚拟机实现内存布局相关的,如果有了直接引用,那么目标一定在内存中存在。

初始化

初始化是类加载过程的最后一步,前面得类加载过程中,除了加载阶段用户应用程序可以通过自定义的类加载器参与之外,其余全部由虚拟机主导和控制。初始化阶段才开始执行类中定义的Java代码。

在准备阶段,变量赋的是系统要求的初始值,在初始化阶段,才会根据程序去赋值。

1
public static int value = 123;

比如以上的value变量,它在准备阶段的初始值是0,在初始化阶段它才会被赋值为123。