12.1 Java中的ClassLoader
类加载子系统,主要作用就是通过多种类加载器(ClassLoader)来查找和加载Class文件到Java虚拟机中。
12.1.1 ClassLoader的类型
- 系统类加载器
- Bootstrap ClassLoader
- Extensions ClassLoader
- Application ClassLoader
- 自定义类加载器
Bootstrap ClassLoader 引导类加载器
C/C++代码实现的加载器,用于加载指定的JDK核心类库,比如java.lang.
、java.util.
等系统类。它用来加载以下目录中的类库 :
- $JAVA HOME/jre/lib 目录。
- -Xbootclasspath 参数指定的目录 。
Java 虚拟机的启动就是通过 Bootstrap ClassLoader 创建一个初始类来完成的。
Extensions ClassLoader
Java 中的实现类为 ExtClassLoader,因此可以简称为ExtClassLoader,它用于加载 Java的拓展类,提供除了系统类之外的额外功能。 ExtClassLoader用来加载以下目录中的类库:
- 加载$JAVA_HOME/jre/lib/ext 目录。
- 系统属性 java.ext.dir所指定的目录。
Application ClassLoader
简称为APPClassLoader,又称为System ClassLoader(系统类加载器),它用来加载以下目录的类库:
- 当前程序的Classpath目录。
- 系统属性java.class.path指定的目录。
12.1.2 ClassLoader的继承关系
12.1.3 双亲委托模式
双亲委托模型:
- 首先判断该Class是否已经加载,如果没有则委托父加载器进行查找
- 依次进行递归,直到委托到最顶层的Bootstrap ClassLoader
- 如果Bootstrap ClassLoader找到了该Class,直接返回;如果没有找到,则继续依次向下查找,如果还没找到最后交由自身去查找。
双亲委托模型的好处:
- 避免重复加载。
- 更加安全。比如无法通过自定义String类替代系统的String类。
12.1.4 自定义ClassLoader
系统提供的类加载器只能够加载指定目录下的 jar 包和 Class 文件,如果想要加载网络上的或者 D 盘某一文件中的 jar 包和 Class 文件则需要自定义 ClassLoader。实现自定义ClassLoader 需要如下两个步骤:
- 定义一个自定义 ClassLoade 并继承抽象类 ClassLoader。
- 复写 findClass 方法,并在 findClass 方提中调用 defineClass 方法。