字节码(.class)文件的加载过程

时间:2022-05-30 17:20:42

字节码文件的装载过程: 加载、连接(包括三个步骤: 验证 准备  解析)、初始化

字节码(.class)文件的加载过程

 

参考: https://blog.csdn.net/qq_20610631/article/details/82709187

 

一、类装载的条件

Java虚拟机规定: 一个类或者接口在初次使用时,必须进行初始化。

这里的使用指主动使用,主动使用有以下几种情况:

1) 当创建一个类的实例时。 比如使用new关键字,或者通过反射、克隆、反序列化方式。

2) 当调用类的静态方式时。即当使用了字节码invokestatic指令

3)当使用类或者接口的静态字段时(final常量除外,此种情况只会加载类而不会进行初始化),即使用getstatic或者putstatic指令(可以使用jclasslib软件查看生成的字节码文件)

4)当使用java.lang.reflect包中的方法反射类的方法时

5)当初始化子类时,必须先初始化父类

6)作为启动虚拟机,含有main方法的那个类

除了以上情况属于主动使用外,其他情况均属于被动使用,被动使用不会引起类的初始化,只是加载了类却没有初始化。

 

二、类装载的过程

1、加载类: 处于类装载的第一个阶段

加载类时,JVM必须完成

1)通过类的全名,获取类的二进制数据流。

2)解析类的二进制数据流为方法区内的数据结构,也就是将类文件放入方法区中

3)创建java.lang.Class类的实例,表示该类型

 

2、连接

2.1 验证字节码

验证字节码文件: 当类被加载到系统后,就开始连接操作,验证就是连接的第一步

主要目的是保证加载的字节码是否符合规范

验证的步骤如图:

字节码(.class)文件的加载过程

 

 2.2 准备阶段

当一个类通过验证后,虚拟机就会进入准备阶段。准备阶段是正式为类变量(static修饰的变量)分配内存并设置类变量初始值,这些内存都将在方法区进行分配。这个时候进行内存分配的仅是类变量,不包括类实例变量,实例变量将会在对象实例化时随着对象一起分配在堆上。为类变量设置初始值是设为其数据类型的“零值”。

比如: public static int num = 10; 这个时候就会为num变量赋值为0

java虚拟机为各种类型变量默认的初始值如表:

类型 默认初始值
int 0
long 0L
short (short)0
char \u0000
boolean false
reference null
float 0f
double 0f

 

 

 

 

 

 

注意:java并不支持boolean类型,对于boolean类型,内部实现试Int, 由于int的默认值是0, 故对应的boolean的默认值是false。

如果类中属于常量的字段,那么常量字段也会在准备阶段被附上正确的值,这个赋值属于java虚拟机的行为,属于变量的初始化。在准备阶段,不会有任何java代码被执行。

 

2.3 解析类

解析阶段的任务就是将类、接口、字段和方法的符号引用直接转为直接引用。

符号引用就是一些字面量的引用。比较容易理解的就是在Class类文件中,通过常量池进行大量的符号引用。