什么是类装载?
我们都知道,Java代码有三个阶段,分别是源代码阶段,类加载阶段,运行阶段。
我们所说的类装载其实就指的就是类加载阶段的Java代码在JVM中的加载过程。
类装载的执行过程
类装载大致可以分为三个阶段,分别是加载,连接,初始化。
其中连接阶段最为复杂,又可以分为验证,准备,解析三个小阶段。
加载
- 根据查找路径找到相应的 class 文件然后导入内存中。
验证
- 检查加载的 class 文件的正确性。
准备(重要)
- 给类中的静态变量分配内存空间,并赋予默认初始值,给常量赋值。
准备阶段是类装载的一个重要阶段,在这个阶段中,JVM会给静态变量赋给默认值,而常量则会直接赋值。
比如:
1 | private static int i = 10; //准备阶段静态变量赋予默认值i=0; |
解析
- 虚拟机将常量池中的符号引用替换成直接引用的过程。符号引用就理解为一个标示,而在直接引用直接指向内存中的地址。
初始化(重要)
- 对静态变量和静态代码块执行初始化工作。类变量(static变量)的赋值语句、静态代码块,最终组成类初始化方法。
初始化
什么时候会发生类的初始化?
- Java虚拟机启动时被标明为启动类的类( JavaTest ),还有就是Main方法的类会首先被初始化。
- 访问某个类或接口的静态变量,或者对该静态变量赋值(在编译器把结果放入常量池的静态字段除外)。
- 初始化某个类的子类,则其父类也会被初始化。
- 创建类的实例,也就是new的方式。
- 反射生成该类的字节码对象。
- 调用类的静态方法 。
对象初始化
- 实例化一个对象的时候,会发生对象的初始化。
- 如果一个类有父类,在实例化子类的时候,会先执行父类的构造函数,然后执行子类的构造函数。
类的初始化和对象初始化的区别
类的初始化 | 对象初始化 |
---|---|
执行静态变量的赋值语句,静态代码块 | 执行成员变量的赋值语句,普通代码块,构造函数代码 |