类加载器以及类加载的双亲委派模型

类加载

加载的作用

加载的作用就是将 .class文件加载到内存。

类加载过程

类加载过程:加载->连接->初始化。连接过程又可分为三步:验证->准备->解析。
在这里插入图片描述

我们可以在类的加载阶段通过自定义类加载器去控制字节流的获取方式(重写一个类加载器的 loadClass() 方法)。

注意数组类型不通过类加载器创建,它由 Java 虚拟机直接创建。


JVM 中内置的三个ClassLoader

  1. BootstrapClassLoader(启动类加载器) :最顶层的加载类,由C++实现,负责加载 %JAVA_HOME%/lib目录下的jar包和类或者或被 -Xbootclasspath参数指定的路径中的所有类。
  2. ExtensionClassLoader(扩展类加载器) :主要负责加载目录 %JRE_HOME%/lib/ext
    目录下的jar包和类,或被 java.ext.dirs 系统变量所指定的路径下的jar包。
  3. AppClassLoader(应用程序类加载器) :面向我们用户的加载器,负责加载当前应用classpath下的所有jar包和类。

类加载的双亲委派模型

什么是双亲委派模型?

在了解双亲委派模型之前,我们需要了解ClassLoader之间的父子关系:
在这里插入图片描述
注意:类加载器之间的“父子”关系也不是通过继承来体现的,是由“优先级”来决定

类加载的时候,系统会首先判断当前类是否被加载过。已经被加载的类会直接返回,否则才会尝试加载。

加载的时候,首先会把该请求委派该父类加载器的 loadClass() 处理,因此所有的请求最终都应该传送到顶层的启动类加载器 BootstrapClassLoader 中。当父类加载器无法处理(因为每个类都有自己加载class的范围,所以会存在加载不到,比如说我们自己写的一个类在没有指定用BootstrapClassLoader 时,BootstrapClassLoader 是加载不到的)时,才由自己来处理。

当父类加载器为null时(null并不代表ExtensionClassLoader没有父类加载器,而是 BootstrapClassLoader),会使用启动类加载器 BootstrapClassLoader 作为父类加载器。

在这里插入图片描述

为什么需要使用双亲委派模型

双亲委派模型可以避免类的重复加载(JVM 区分不同类的方式不仅仅根据类名,相同的类文件被不同的类加载器加载产生的是两个不同的类),也保证了 Java 的核心 API 不被篡改。如果没有使用双亲委派模型,而是每个类加载器加载自己的话就会出现一些问题,比如我们编写一个称为 java.lang.Object类的话,那么程序运行的时候,系统就会出现多个不同的 Object 类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值