一文搞懂ClassLoader类加载机制

本文详细介绍了Java的ClassLoader加载机制,包括ClassLoader的作用、内置的Bootstrap、Extension和AppClassLoader,以及双亲委托模型的工作原理。类加载过程分为加载、验证、准备、解析和初始化五个阶段,每个阶段都有具体的执行细节。双亲委托模型确保了类的全局唯一性,避免了类被重复加载。此外,文章还探讨了类加载的触发条件和主动、被动引用的区别。
摘要由CSDN通过智能技术生成

ClassLoader类加载机制


一、什么是ClassLoader?

      ClassLoader类加载器,它的具体作用就是讲Class文件加载到JVM虚拟机中去,程序就可以正常运行了。但是JVM启动的时候并不会一次性加载所有的class文件,而是根据需要去动态加载。

二、Java内置的3类Classloader

1.Bootstrap ClassLoader

      java最顶层的、程序引导启动的类加载器,主要加载核心类库:%JRE_HOME%\lib下的rt.jar、resources.jar、charsets.jar和class等,对应用不可见。

2.Extention ClassLoader

      扩展类的加载器,默认家在目录%JRE_HOME%\lib\ext目录下的jar和class文件。

3.AppClassLoader

      也称SystemAppClassLoader
      加载当前应用的classpath的所有类,即应用程序依赖的jar和本身的class文件中定义的类。

三个类加载器,可以通过指定参数来改变或追加扫描路径

ClassLoader类型 参数类型 说明
Bootstrap ClassLoader -Xbootstrapclasspath: 设置Bootstrap ClassLoader的搜索路径
-Xbootstrapclasspath/a: 把路径添加到已存在搜索路径的后面
-Xbootstrapclasspath/b: 把路径添加到已存在搜索路径的前面
Extention ClassLoader -Djava.ext.dir 设置Bootstrap ClassLoader的搜索路径
AppClassLoader -Djava.class.path=或者-cp-classpath 设置AppClassLoader的搜索路径

三、ClassLoader约定的类加载机制—双亲委托模型

      当一个类加载器接收到一个类加载的任务时,不会立即加载,而是将加载任务委托给它的父类加载器去执行,每一层的类都采用相同的方式,直接委托给最顶层的启动类加载器为止。如果父类加载器无法加载委托给它的类,便将类的加载任务退回给下一级类加载器去执行加载。
      使用双亲委托机制的好处是:能够有效确保一个类的全局唯一性,当程序中出现多个限定名相同的类时,类加载器在执行加载时,始终只会加载其中的某一个类。
      双亲委托模型对于保证JAVA程序的稳定运作很重要,但它的实现却非常简单,实现双亲委托的代码都集中在java.lang.ClassLoader的loadClass()方法中,逻辑清晰易懂:先检查是否已经倍加再过,若没有加载则调用父类加载器的loadClass()方法,若父加载器为空则默认使用启动类加载器作为父加载器。如果父类加载器加载失败,包出ClassNotFoundException异常后,在调用自己的findClass方法进行加载。

在这里插入图片描述

时序图解析:
      1.一个APPClassLoader查找资源时,先查看缓存中是否存在,缓存有从缓存中获取,否则委托给父类加载器。
      2.重复第1步的操作。
      3.如果ExtClassLoader也没有加载过,则有BootstrapClassLoader加载,首先查找缓存,没有查到就去扫描自己规定的路径,sun.mic.boot.class下面的路径,找到就返回,否则让子加载器自己加载。
      4.Bootstrap ClassLoader如果没有找到,则ExtClassLoader自己在java.ext.dirs路径中扫描,查到就返回,否则继续向下让子加载器查找。
      5.ExtClassLoader查不到,AppClassLoader就自己扫描,在java.class.path路径下查找,找到就返回,如果没有找到就让子类扫描。如果没有子类了就会抛出异常。

四、双亲委托模型

      双亲委托模型为什么会这样加载?我们还需要了解ClassLoader类,尤其是重要的方法loadClass()、findLoadedClass()、findClass()、defineClass()。
      ClassLoader是所有类加载器(BootstrapClassLoader除外,因为它是JVM层面的类加载器)的最顶级基类,他有一个ClassLoader类型parent字段,及它的父类加载器,注意这里不是父类,一个类加载器和父类加载器是组合关系,不是继承关系。

ClassLoader部分方法定义

public abstract class ClassLoader {
   
private final ClassLoader parent;
public Class<?> loadClass(String name) throws ClassNotFoundException;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值