我们都知道 Java 程序的运行是以 JVM 为基础的,JVM 即 Java 虚拟机。

而 JVM 会默认提供三个主要的类加载器:

  • BootStrap:引导类加载器
  • ExtClassLoader:扩展类加载器
  • AppClassLoader:系统类加载器

分别详细介绍下:

BootStrap 是用来加载 Java 的核心库,是用原生代码来实现的,并不继承自 java.lang.ClassLoader;

ExtClassLoader 加载 JVM 提供的扩展库目录下的 Java 类;

AppClassLoader 是根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。

除了 BootStrap 外,每个类加载器都有一个「父'类加载器」,通过类加载器调用 getParent() 方法能够得到他的「父'类加载器」。

现实项目中,我们可能会编写自己的类去继承「java.lang.ClassLoader」来实现我们自己的类加载器,从而达到某种目的。一般我们创建的类加载器的「父'类加载器」是 AppClassLoader。

而 AppClassLoader 的「父'类加载器」是ExtClassLoader;

ExtClassLoader 的「父'类加载器」则是 BootStrap。

所以我们使用类加载器的结构用一张「树形图」可以很直白的表现出来。


Java指定类使用固定的类加载器 java默认的类加载器_vs 未能加载此自定义查看器


为了校验,写了一个简单的例子来验证一下:


Java指定类使用固定的类加载器 java默认的类加载器_vs 未能加载此自定义查看器_02


得到的结果是


Java指定类使用固定的类加载器 java默认的类加载器_加载_03


我们自定义的类加载器的父类加载器是 AppClassLoader;

而 AppClassLoader 的父类加载器是 ExtClassLoader;

ExtClassLoader 的父类加载器打印是 null,原因是他并不是 java 类。

好了,类加载器的层级结构我们明白之后,我们再来看下类加载器的委托机制

双亲委托

我们先来看个例子吧,这个例子由 eclipse 编写

例1:


Java指定类使用固定的类加载器 java默认的类加载器_Java_04


打印的结果是


Java指定类使用固定的类加载器 java默认的类加载器_Java_05


说明了加载我们当前类的类加载器是 AppClassLoader

而 System 是属于系统提供jar类:rt.jar 中的类,所以是由 BootStrap 加载的,所以返回结果为 null。

不过这个例子并不能观察出 “类加载器的委托机制”。我们需要将此项目打包成 jar 文件,然后再放到 ext/目录 下,然后再来运行看看:

例2:


Java指定类使用固定的类加载器 java默认的类加载器_vs 未能加载此自定义查看器_06


Java指定类使用固定的类加载器 java默认的类加载器_加载_07


这个时候发现打印结果是不是变成了 ExtClassLoader。

对比一下我们在 eclipse 运行的代码 打印结果是 AppClassLoader,是不是看出点什么端倪?

其实这只是类加载器的委托机制的表象,我们还是看一下它的加载机制是什么吧。

我们自定义的类会向 AppClassLoader 发送加载请求

AppClassLoader 会向 ExtClassLoader 发送加载请求

ExtClassLoader 则会向 BootStrap 发送加载请求

此时 BootStrap 由于没有父类加载器,所以他会尝试加载我们自定义的类,但是由于BootStrap 的职责是加载 Java 的核心库,而在核心库中并未找到自定义类,所以无法加载。

此时会将加载权给 ExtClassLoader,ExtClassLoader 的职责是加载 lib/ext 库中的库,而我们第一个例子中没有将 jar 包放到 ext 目录下,所以第一个例子中 ExtClassLoader 没有加载到。

而第二个例子中,我们把 jar 包放到了 ext 下,所以 ExtClassLoader 加载到了。

继续第一个例子,ExtClassLoader 没有加载到自定义类,所以把加载权给了 AppClassLoader,而 AppClassLoader 就是为加载这种自定义类而存在的,自然也就加载了。

整理成流程图则是这样的


Java指定类使用固定的类加载器 java默认的类加载器_加载_08


下篇网站我会创建一个自定义的类加载器,然后分析一下 ClassLoader 类的加载流程。