jvm系列之认识类加载器

284 阅读5分钟

Hello,小伙伴们,大家晚上好,今天我们来肝类加载器,等等,你说肝就肝啊,我就不想肝,是的,肝任何新知识的时候,我们都需要清楚我们脑子到底想不想肝,于是我们抛出了灵魂三问,清楚一下我们学习的目的。

灵魂三问: 问题1:什么是类加载器? 问题2:学习它有哪些好处呢? 问题3:学习成本呢?

1.什么是类加载器? 简单来说就是用来加载类的,就像我们用老一点的那个DvD机一样,当你把光盘放到那个读碟机里,屏幕上总要显示三个字:读碟中。。。这就是加载,把光盘中的信息读取出来,再放到电视上,经过显像管进行成像,简单理解即可。

2.学习它有哪些好处呢? 一方面学习类加载器可以让我们知道jvm是通过什么手段加载一个类的,另一方面为我们在运行程序的时候遇到找不到类或者方法的时候提供排除故障的参考思路,也可以动态加载某类和某jar包,这个好处不言而喻,美食也只有实际品尝过,才知道真香!

3.学习成本呢? 学习成本的话:只需要带个脑子,带个电脑就行了,时间的话需要两个小时左右吧,评估了一下可以接受,好处不是很明显,但也能接受,苍蝇再小那也是肉啊,决定肝了!

一、类的生命周期 java这种面向对象的高级语言,肯定是源于生活啊,我们生活中的生命都会有一个生命周期,我们每个人也都会经历出生,成年,老年,消亡的过程,同样,每个类也有自己的生命周期,一般类的加载会经过7个步骤,也就是类的加载过程,有时候面试也会问到,小伙,知道你java玩的溜,知道类的加载过程嘛?

(1)类的加载过程 类的加载一般要经历7个步骤:1.加载 2.验证 3.准备 4.解析 5.初始化 6.加载 7.卸载。我一看,惊了,这么多步骤我也记不下来呀,必须偷点懒,今天先记三个,那就记:1.加载,2,3,4合成一个步骤就叫链接吧,接着就是类的初始化,我思考了一会,能不能再简化一点,enenen,那恐怕得去写个jvm了!

(2)类的加载细节 知道了类的加载过程,那每一步都是肝什么捏?怎么肝的~( ̄▽ ̄)~*?首先是加载:加载就是找字节流,说白了就是找到我们的Class文件,这是创建类的原材料,之后就是链接:链接细分为三个阶段:1.验证,2.准备,3.解析。验证阶段看我们加载的文件格式是否正确,依赖是否完备。准备呢,则是为被加载类的静态字段分配内存。解析呢,主要是把我们的符号引用,解析成实际引用。这个很好理解,就是类在被加载之前,类是不知道它的方法和字段的地址的,那在引用的时候,Java编译器都会生成一个符号引用,来定位需要的字段和方法,解析阶段的目的,正是将这些符号引用解析成为实际引用。如果符号引用指向一个未被加载的类,或者未被加载类的字段或方法,那么解析将触发这个类的加载(但未必触发这个类的链接以及初始化。)

接下来是初始化:主要是初始化构造方法,如果我们要初始化一些静态字段可以使用静态代码块,如果直接赋值的静态字段被 final 所修饰,并且它的类型是基本类型或字符串时,那么该字段便会被 Java 编译器标记成常量值(ConstantValue),其初始化直接由 Java 虚拟机完成。除此之外的直接赋值操作,以及所有静态代码块中的代码,则会被 Java 编译器置于同一方法中,并把它命名为 < clinit >。

简单来说,类的初始化主要是:1.为标记为常量值的字段赋值,2.执行 < clinit > 方法。Java 虚拟机会通过加锁来确保类的 < clinit > 方法仅被执行一次。

进入到这一步骤,就可以进行类的使用和接下来的卸载了。

二、类加载器

类加载器有哪些? 肝完类的加载机制,接着肝类的加载器,java里面的类加载器有三个:1.启动类加载器,主要加载rt.jar等java核心的jar包的。2.应用类加载器,主要是加载我们自己写的java类,3.扩展类加载器,那为啥还要有扩展类加载器呢,主要是因为我们的这个依赖关系比较复杂,每个应用都可能依赖很多共性的jar包,那我们就可以把这些jar抽取出来,然后放到一个扩展包中,用扩展类加载器进行统一的加载。

类加载器的特点 1.就是双亲委派,这个好理解,就是为了保证类不重复加载,每个类加载器在加载的时候都会先去看看父类加载器是否加载,如果加载过了,那就返回一个引用就可以使用了,如果都不加载自己才加载 2.处理依赖,我们经常会遇到,一个类里面有多个类的时候,那当前类加载器在加载这个类的时候也要负责把它依赖的类也进行加载。 3.缓存加载:任何一个类只被加载一次,加载结束后就会缓存在内存里,下次取的时候从缓存取,执行效率比较高。 4.当然也可以自定义类加载器。

结束语 肝了这么久,终于要结束了,就能去开心的刷视频了,哈哈哈!