ClassLoader类加载机制

简介: 一、类加载器   类加载器(ClassLoader),顾名思义,即加载类的东西。在我们使用一个类之前,JVM需要先将该类的字节码文件(.class文件)从磁盘、网络或其他来源加载到内存中,并对字节码进行解析生成对应的Class对象,这就是类加载器的功能。

一、类加载器

  类加载器(ClassLoader),顾名思义,即加载类的东西。在我们使用一个类之前,JVM需要先将该类的字节码文件(.class文件)从磁盘、网络或其他来源加载到内存中,并对字节码进行解析生成对应的Class对象,这就是类加载器的功能。我们可以利用类加载器,实现类的动态加载。

二、类的加载机制

  在Java中,采用双亲委派机制来实现类的加载。那什么是双亲委派机制?

从以上描述中,我们可以总结出如下四点:

1、类的加载过程采用委托模式实现

2、每个 ClassLoader 都有一个父加载器。

3、类加载器在加载类之前会先递归的去尝试使用父加载器加载。

4、虚拟机有一个内建的启动类加载器(bootstrap ClassLoader),该加载器没有父加载器,但是可以作为其他加载器的父加载器。

Java 提供三种类型的系统类加载器。

  第一种是启动类加载器,由C++语言实现,属于JVM的一部分,其作用是加载 <Java_Runtime_Home>/lib 目录中的文件,并且该类加载器只加载特定名称的文件(如 rt.jar),而不是该目录下所有的文件。(除了指定目录外还必须是特定名称的文件才加载。)

  另外两种是 Java 语言自身实现的类加载器,包括扩展类加载器(ExtClassLoader)和应用类加载器(AppClassLoader),扩展类加载器负责加载<Java_Runtime_Home>\lib\ext目录中或系统变量 java.ext.dirs 所指定的目录中的文件。

  应用程序类加载器负责加载用户类路径中的文件。用户可以直接使用扩展类加载器或系统类加载器来加载自己的类,但是用户无法直接使用启动类加载器,

  除了这两种类加载器以外,用户也可以自定义类加载器。

  加载流程如下图所示:

  

注意:这里父类加载器并不是通过继承关系来实现的,而是采用组合实现的。见下图一

启动类加载器属于 JVM 的一部分,它不是由 Java 语言实现的,在 Java 中无法直接引用,返回空。双亲委派机制仍旧有效,见下图二

 

 

从源码可以看出,ExtClassLoader 和 AppClassLoader都继承自 ClassLoader 类,ClassLoader 类中通过 loadClass 方法来实现双亲委派机制。

整个类的加载过程可分为如下三步:

  1、查找对应的类是否已经加载。

  2、若未加载,则判断当前类加载器的父加载器是否为空,不为空则委托给父类去加载,否则调用启动类加载器加载(findBootstrapClassOrNull 再往下会调用一个 native 方法)。

  3、若第二步加载失败,则调用当前类加载器加载。

  通过上面这段程序,可以很清楚的看出扩展类加载器与启动类加载器之间是如何实现委托模式的。

 

 自定义加载器的注意事项:

通常情况下,我们都是直接使用系统类加载器。但是,有的时候,我们也需要自定义类加载器。比如应用是通过网络来传输 Java 类的字节码,为保证安全性,这些字节码经过了加密处理,这时系统类加载器就无法对其进行加载,这样则需要自定义类加载器来实现。自定义类加载器一般都是继承自 ClassLoader 类,从上面对 loadClass 方法来分析来看,我们只需要重写 findClass 方法即可。 

自定义类加载器的核心在于对字节码文件的获取,如果是加密的字节码则需要在该类中对文件进行解密。

有几点需要注意:

  1、这里传递的文件名需要是类的全限定性名称,即com.tt.b2b.test.Test格式的,因为 defineClass 方法是按这种格式进行处理的。

  2、最好不要重写loadClass方法,因为这样容易破坏双亲委托模式。

  3、这类 Test 类本身可以被 AppClassLoader 类加载,因此我们不能把 com/tt/b2b/test/Test.class 放在类路径下。否则,由于双亲委托机制的存在,会直接导致该类由 AppClassLoader 加载,而不会通过我们自定义类加载器来加载。

 

  双亲委派机制能很好地解决类加载的统一性问题。对一个 Class 对象来说,如果类加载器不同,即便是同一个字节码文件,生成的 Class 对象也是不等的。也就是说,类加载器相当于 Class 对象的一个命名空间。双亲委派机制则保证了基类都由相同的类加载器加载,这样就避免了同一个字节码文件被多次加载生成不同的 Class 对象的问题。但双亲委派机制仅仅是Java 规范所推荐的一种实现方式,它并不是强制性的要求。

 

目录
相关文章
|
4月前
|
前端开发 安全 Java
JVM ClassLoader 类加载器
类加载器,即ClassLoader,它负责加载class文件,class文件在文件开头有特定的文件标示,并且ClassLoader只负责class文件的加载,至于它是否可以运行,则由Execution Engine决定。
|
10月前
|
前端开发 Java 开发者
什么是类加载器,类加载器有哪些?
什么是类加载器,类加载器有哪些?
63 0
|
8月前
|
缓存 前端开发 安全
深入理解Java类加载器(ClassLoader)
深入理解Java类加载器(ClassLoader)
233 0
|
9月前
|
前端开发 Java C++
jvm组成-类加载器
了解jvm组成-类加载器
42 0
|
10月前
|
前端开发 Java 开发者
JVM的类加载器
JVM(Java虚拟机)的类加载器(ClassLoader)是Java程序中负责加载Java类文件的组件。类加载器在运行时动态地将类文件加载到JVM中,并生成对应的Class对象,使得Java程序能够使用这些类。
61 0
|
10月前
|
前端开发 Java 数据库
什么是类加载器?类加载器有哪些?
类加载器(ClassLoader)是Java虚拟机(JVM)的一部分,用于将类的字节码加载到内存中,并生成对应的Class对象。类加载器负责查找、加载和链接类的过程。
202 0
|
11月前
|
前端开发 安全 Java
JVM类加载器
JVM类加载器
|
缓存 前端开发 安全
|
XML 前端开发 Java
Java虚拟机系列: ClassLoader类加载机制
改不完的 Bug,写不完的矫情。公众号 杨正友 现在专注移动基础开发 ,涵盖音视频和 APM,信息安全等各个知识领域;只做全网最 Geek 的公众号,欢迎您的关注!
76 0
Java虚拟机系列: ClassLoader类加载机制
|
安全 前端开发 Java
双亲委派模型与类加载器
我们都知道类都是通过类加载器被加载进虚拟机中的,那这个类加载器有哪些呢?我们平时写的代码又是通过什么类加载器被加载进虚拟机中的呢?类加载器的工作模式又是什么呢?带着疑问一起去学习下双亲委派模型与类加载器。
102 0
双亲委派模型与类加载器