JVM的类加载过程

目录

1、加载

2、连接

a) 验证

b) 准备

c) 解析

静态解析

动态解析

3、初始化


参考引用 小破站寒食君-Java类加载机制这块算是玩明白了

上 《Java程序设计》 的上机课时,相信大家都用过 javac 这个命令,比如:javac hello.java,如图:

我们知道,hello.java文件经过 javac编译 之后会产生 class文件,也就是字节码文件。那么接下来我们重点聊聊Java是怎么通过类加载去处理字节码文件

首先,类加载由三个阶段组成,分别是

  1. 加载
  2. 连接
  3. 初始化

.class文件不仅仅是指javac编译之后的。class文件,还包含各种来源的二进制流,比如网络、数据库。

如下图

1、加载

在加载之前,会进行文件格式验证 之后再进行加载。加载是一个读取Class文件,将其转换成某种静态数据结构存储在方法区内,并在中生成一个便于用户调用的java.lang.Class类型的对象的过程。

2、连接

连接又细分为3个阶段,分别是

  1. 验证
  2. 准备
  3. 解析

a) 验证

类加载的加载阶段把Class文件转换成静态数据结构存储在方法区,在这之前是不是只经过了文件格式验证

假设文件格式正确之后一路开绿灯,是不是会对 jvm 的安全构成威胁,那么在开绿灯之前就必须得经过安全验证,也就是对元数据、字节码进行语法、语义上的分析,保证不会危害 jvm。

b) 准备

验证后发现是安全的,那么该干啥就去干啥呗。所以进入了准备阶段。

准备阶段的工作很简单,就是为类型中定义的静态变量初始化,比如 static private int b -> b=0

c) 解析

最后到了连接的最后一个小阶段-解析,解析的工作就是把符号引用替换成直接引用。

在此之前,先说下符号引用和直接引用两个概念以及埋下静态解析动态解析.

静态解析

符号引用:当一个Java类被编译成Class文件之后,假如这个类称为A,A中引用了B。在编译阶段,B没有被编译,也一定没有被加载,所以A不知道B的实际地址。此时在A的Class文件中,用字符串S表示B,S就被称为符号引用。

直接引用:在运行时,如果A发生了类加载,但是到了解析阶段发现B还没有被加载,就会触发B的类加载,把B加载到虚拟机中,此时符号引用被替换成B的实际地址,也就是直接引用。

动态解析

阐述完上面两个概念之后,我们也就知道了静态解析,所以根据静态解析我们很容易就会想到另外一个词,动态解析。

我们知道Java是多态的,所以当一个抽象类或接口有多个实现类时,怎么知道要加载哪个实现类呢?

既然不知道加载哪个实现类,那就等一等。直到运行过程中发生了调用,此时虚拟机调用栈中将会得到具体的类型信息,这时候再进行解析,这时候就能用直接引用替换符号引用。

这也解释了为什么解析会发生在初始化之前初始化之后。

3、初始化

当解析步骤完成之后,说明整个连接阶段的完成。也意味着外部的Java类已经成功引入到你的程序中。

最后对类进行初始化,判断 是否有主动的资源初始化操作。

主动的资源初始化就是成员变量的赋值,静态成员变量的赋值、静态代码块的逻辑;而不是指构造函数里的操作。前者是Class层面,后者是对象层面。

最后,完成类加载,开始使用!

  • 18
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值