类加载器ClassLoader的理解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了类加载器ClassLoader的理解相关的知识,希望对你有一定的参考价值。

  最近在做一个热加载Class的小组件,这个组件需要对类加载器ClassLoader有所了解,我就顺便借这个机会把学到的一点皮毛与大家分享一下。

 从Class文件开始

ClassLoader,顾名思义就是类加载器。简单的说就是把Class文件加载到JVM中,之后程序就能正常的运行了。

我们平时写的代码都是.java格式的文件,但是这个文件是不能够直接运行的。比如下面这个简单的测试程序Test.java

1 public class Test {
2 
3     public static void main(String[] args) {
4         System.out.println("Testing");
5     }
6 }

在文件夹下看,就是这么一个文件:

技术分享

 

我们在命令行下编译一下这个Java文件:

1 javac Test.java 

然后就可以在目录下看到生成的class文件,也就是JVM可以识别运行的文件。

技术分享

 

Java自带的类加载器

在介绍类路径之前,先来聊一下环境变量。

 

Java自带有三个类加载器:

 

Bootstrap ClassLoader:主要加载核心类库,%Java_HOME%\\lib 下的rt.jar、resources.jar、charsets.jar和class等,总之就是jdk安装目录下lib目录下的一些核心jar包。

Extention ClassLoader 扩展的类加载器,主要加载目录%JRE_HOME%\\lib\\ext目录下的jar包和class文件,就是JRE安装目录下lib目录下ext目录下的jar和class文件。

Appclass Loader也称为SystemAppClass应用程序加载器 加载当前应用的classpath的所有类,这个就是很好理解了,就是我们平时自己写的项目类路径下的类。

 

 

双亲委派机制

接下来我先祭出一张常见的图:

技术分享

 

双亲委派机制的意思是:一个类加载器遇到一个加载类的请求,首先不会自己去加载,而是看自己的父加载器能否加载这个类,然后一级一级往上传直到遇到能够加载这个类的加载器。

简单可以形容为一家几口吃苹果:
小明:爸爸,这苹果你吃吗?
小明的爸爸:我先问问你爷爷,爸,这苹果你吃吗?
小明的爷爷:你们真孝顺,那我就恭敬不如从命啦。

如果遇到顶层的父类加载器无法加载,该怎么办?这个时候,就往下找,找到第一个能加载这个类的加载器
小明:爸爸,这苹果你吃吗?
小明的爸爸:我先问问你爷爷,爸,这苹果你吃吗?
小明的爷爷:牙不好啦,我不吃啦你们吃吧。
小明的爸爸:好的,我的牙口还不错,那我就吃了。

 

那么为什么需要一个机制呢,原因主要是为了避免类加载程序的混乱。

比如Java官方指定了一个java.lang.String类,然后你自己又重新写了一个java.lang.String类的类。这个时候,你想import一个String类型,就没有办法判断到底这个String是哪个String了。

当然这边要多说一句,父类加载器不等于父类,也就是上面的三个类加载器并不是继承关系。

 

自定义ClassLoader

刚刚那张图大家应该已经发现了,除了三个系统自带的ClassLoader以外,最底层还有几个自定义的类加载器。

没错,原来的类加载器只是按照特定的方式加载指定目录下的jar包,那么如果你想按照自己的要求加载一些东西呢?这就需要你自己去定义一个classloader了。

比如以我为例,我希望可以多次重新加载同一个Class。

可是在ClassLoader中的加载class的方法loadClass()中,有一个  findLoadedClass() 方法来判断Class是否已经被加载的操作,不符合要求,而且loadClass()方法中也会按照双亲委派去找寻父类加载器,不符合要求。

我的步骤

  1. 编写一个类继承自ClassLoader抽象类。 
  2. 复写它的findClass()方法,直接调用findClass()来找寻Class文件,而不是loadClass()。
  3. findClass()方法中调用defineClass(),defineClass()将class二进制内容转换成Class对象。 

这样子,就实现了我的热加载Class的目的。

 









以上是关于类加载器ClassLoader的理解的主要内容,如果未能解决你的问题,请参考以下文章

深入理解JVM中的ClassLoader类加载器

对类加载器(ClassLoader)的理解

深入理解类加载器和双亲委派模型

类加载器盲区整理

类加载器深入理解和双亲委托模型的案例分析

类的加载与ClassLoader的理解