图 1. 类装入器委托模型
与其他类装入器不同,引导类装入器(也称作基本(primordial) 类装入器)不能由 Java 代码实例化。(通常是因为它是作为 VM 本身的一部分实现的。)这个类装入器可以从启动的类路径装入核心系统类,通常是位于 jre/lib 目录的 JAR 文件。但是能用 -Xbootclasspath 命令行选项修改这个类路径(稍后介绍)。
扩展(extension) 类装入器(也称作标准扩展 类装入器)是引导类装入器的一个孩子。它的主要职责是从扩展目录装入类,通常位于 jre/lib/ext 目录。这提供了简单地访问新扩展的能力,例如不同的安全扩展,不需要修改用户的类路径即可实现。
系统(system) 类装入器(也称作应用程序 类装入器)负责从 CLASSPATH 环境变量指定的路径装入代码。默认情况下,这个类装入器是用户创建的任何类装入器的父类。这也是 ClassLoader.getSystemClassLoader() 方法返回的类装入器。
类路径选项
表 1 总结了设置三个标准类装入器的类路径的命令行选项:
表 1. 类路径选项
| 命令行选项 |
解释 |
涉及的类装入器 |
-Xbootclasspath:<用 ; 或 : 分隔的目录和 zip/JAR 文件> |
设置引导类和资源的搜索路径。 |
涉引导 |
-Xbootclasspath/a:<用 ; 或 : 分隔的目录和 zip/JAR 文件> |
把路径添加到启动类路径的末尾。 |
引导 |
-Xbootclasspath/p:<用 ; 或 : 分隔的目录和 zip/JAR 文件> |
把路径添加到启动类路径的前面。 |
引导 |
-Dibm.jvm.bootclasspath=<用 ; 或 : 分隔的目录和 zip/JAR 文件> |
这个属性的值被用作额外的搜索路径,它被插到 -Xbootclasspath/p: 定义的值和启动类路径之间。启动类路径或者是默认值,或者是 -Xbootclasspath: 选项定义的值。 |
引导 |
-Djava.ext.dirs=<用 ; 或 : 分隔的目录和 zip/JAR 文件> |
指定扩展类和资源的搜索路径。 |
扩展 |
-cp or -classpath <用 ; 或 : 分隔的目录和 zip/JAR 文件> |
设置应用程序类和资源的搜索路径。 |
系统 |
-Djava.class.path=<用 ; 或 : 分隔的目录和 zip/JAR 文件> |
设置应用程序类和资源的搜索路径。 |
系统 |
类装入的阶段
类的装入实际上可以分成三个阶段:装入、链接和初始化。
虽然不是所有的问题,但至少大多数与类装入有关的问题都可以追溯到在这三个阶段中发生的某个问题。所以,对于每一阶段的深入理解有助于对类装入问题的诊断。图 2 显示了这三个阶段:
图 2. 类装入的阶段
装入 阶段包括:找到必要的类(通过查找每个类路径)并装入字节码。在 JVM 中,装入阶段为类对象提供了非常基本的内存结构。在这一阶段不处理方法、字段和引用的其他类。所以,类还不能使用。
链接 是三个阶段中最复杂的一个。可以把它分成三个主要阶段: