java学习笔记74:类加载器

1、类加载器概述

在开发中会遇到 java.lang.ClassNotFoundException 和 java.lang.NoClassDefError,想要更好解决这类问题,或者在一些特殊的应用场景,比如需要支持类的动态加载或需要对编译后的字节码文件进行加密解密操作,那么需要你自定义类加载器,因此了解类加载器及其加载机制成为了Java开发必备技能之一。

2、四种类加载器
2.1 引导类加载器(Bootstrap Classloader),又称为根类加载器

​ 它负责加载 Java 的核心库(JAVA_HOME/jre/lib/rt.jar 等或 sun.boot.class.path 路径下的内容),是用原生代码(C/C++)来实现的,并不继承自 java.lang.ClassLoader,所以通过 Java 代码获取引导类加载器对象将会得到 null。(只有核心类库如 String 才使用 引导类加载器)

2.2 扩展类加载器(Extension Classloader)

​ 它由 sun.misc.Launcher$ExtClassLoader 实现,是 java.lang.ClassLoader 的子类,负责加载 Java 的扩展库(JAVA_HOME/jre/ext/*.jar或java.ext.dirs路径下的内容)

2.3 应用程序类加载器(Application Classloader)

​ 它由 sun.misc.Lanuncher$AppClassLoader 实现,是 java.lang.ClassLoader 的子类,负责加载 Java 应用程序类路径(classpath、java.class.path)下的内容。(通俗的讲:项目的路径bin文件夹下的字节码,以及如果你配置了环境变量classpath)

2.4 自定义类加载器

​ 开发人员可以通过继承java.lang.ClassLoader类的方式实现自己的类加载器,以满足一些特殊的需求,例如对字节码进行加密来避免class文件被反编译,或者加载特殊目录下的字节码数据。

小结:类加载器是用来完成类加载的。

3、经典委托模式
3.1 Java 中类加载器的双亲委托模式
  • 类加载器负责加载所有的类,系统为所有被载入内存中的类生成一个java.lang.Class实例。一旦一个类被载入JVM中,同一个类就不会被再次载入了。
  • 在JVM中,一个类用其全限定类名和其类加载器作为其唯一标识。换句话说,同一个类如果用两个类加载器分别加载,JVM将视为“不同的类”,它们互不兼容。
  • “双亲委派模型(Parent Delegation Model)”,类加载器在执行类加载任务的时候,确保一个类的全局唯一性

按照双亲委派模型的规则,除了引导类加载器之外,程序中的每一个类加载器都应该拥有一个超类加载器

比如:ExtClassLoader的超类加载器是引导类加载器,而AppClassLoader的超类加载器是ExtClassLoader,而自定义类加载器的超类就是AppClassLoader。

在这里插入图片描述

​ 那么当一个类加载器接收到一个类加载任务的时候,它并不会立即展开加载,先检测此类是否加载过,即在方法区寻找该类对应的Class对象是否存在,如果存在就是已经加载过了,直接返回该Class对象,否则会将加载任务委派给它的超类加载器去执行,每一层的类加载器都采用相同的方式,直至委派给最顶层的启动类加载器为止,如果超类加载器无法加载委派给它的类时,便会将类的加载任务退回给它的下一级类加载器去执行加载,如果所有的类加载器都加载失败,就会报java.lang.ClassNotFoundException或java.lang.NoClassDefFoundError。

在这里插入图片描述

在此大家需要注意,由于Java虚拟机规范并没有要求类加载器的加载机制一定要使用双亲委托模式,只是建议采用这种方式而已。比如在Tomcat中,类加载器所采用的加载机制就和传统的双亲委派模型有一定区别,当缺省的类加载器就接收到一个类的加载任务时,首先会由它自行加载,当它加载失败时,才会将类的加载任务委派给它的超类加载器去执行,这同时也是Servlet规范推荐的一种做法。

数组类型本身并不是由类加载器负责创建,而是由JVM在运行时根据需要而直接创建的,但数组的元素类型仍然需要依靠类加载器去创建。因此,JVM会把数组元素类型的类加载器记录为数组类型的类加载器。

3.2 双亲委托模式目的是什么?

目的:为了安全,而且各司其职,保证核心类库的安全性

4、类加载器的作用
  • 加载类
  • 加载“类路径下”的资源文件。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值