从Java虚拟机的角度来讲,只存在两种不同的类加载器:一种是启动类加载器(Bootstrap ClassLoader),这个类加载器使用C++语言实现(只限于HotSpot),是虚拟机自身的一部分;
另一种就是所有其他的类加载器,这些类加载器都由Java语言实现,独立于虚拟机外部,并且全都继承自抽象类java.lang.ClassLoader。
从Java开发人员的角度来看,类加载器还可以划分得更细致一些,不过,这里需要区分JDK的版本,在JDK 1.8及之前的版本,和之后的版本是不太一样的。主要是因为JDK 1.9中提供了Jigsaw实现模块化,导致类加载器发生了一些变化。
在JDK1.9中,原来的扩展类加载器被重命名为平台类加载器—PlatformClassLoader** 。它主要加载的是那些属于Java平台模块系统的非核心模块。这些模块在 module-info.java 文件中被明确声明。
JDK 1.8 以前会使用到以下3种系统提供的类加载器。
在JDK 9中,类加载器发生了一些变化,原来的扩展类加载器被重命名为平台类加载器—PlatformClassLoader** 。
PlatformClassLoader 负责加载JDK平台本身的类库,这些类库位于JDK的 lib 目录下,但不包括核心的 java.* 类库(这些由启动类加载器加载)。它主要加载的是那些属于Java平台模块系统的非核心模块。这些模块在 module-info.java 文件中被明确声明。
很多人因为知道双亲委派这个词,就以为这些类加载器之间是继承关系,但是其实不是的。他们之间是组合关系。
在ClassLoader类中有一个ClassLoader类型的成员变量,他叫parent,他其实就是代表着当前类的上一层类加载器。
public abstract class ClassLoader {
// The parent class loader for delegation
// Note: VM hardcoded the offset of this field, thus all new fields
// must be added *after* it.
private final ClassLoader parent;
}
这就是通过组合而不是继承引入进来的,当我们想要把一个类委派给上层类加载加载时,直接调用parent.loadClass即可,如 代码: