Java 教程是为 JDK 8 编写的。本页中描述的示例和实践未利用在后续版本中引入的改进。
理解扩展类加载
扩展框架使用类加载委托机制。当运行时环境需要为应用程序加载新类时,它将按顺序在以下位置查找该类:
- Bootstrap classes (引导类):rt.jar 中的运行时类,i18n.jar 中的国际化类等。
- Installed extensions (安装型扩展):JRE 的 lib/ext 目录中的 JAR 文件中的类,以及系统范围内特定于平台的扩展目录(例如 Solaris 操作系统中的 /usr/jdk/packages/lib/ext,但请注意,此目录的使用仅适用于 Java™ 6 及更高版本。
- The class path (类路径):类,包括 JAR 文件中的类,由系统属性 java.class.path 指定的路径。如果类路径上的 JAR 文件具有带有
Class-Path
属性的清单,则还将搜索由 Class-Path
属性指定的 JAR 文件。默认情况下,java.class.path
属性的值为 .
,即当前目录。你可以使用 -classpath 或 -cp 命令行选项或设置 CLASSPATH
环境变量来更改该值。命令行选项会覆盖 CLASSPATH
环境变量的设置。
优先级列表告诉你,例如,只有在 rt.jar,i18n.jar 或安装型扩展未找到要加载的类时,才会搜索类路径。。
除非你的软件出于特殊目的而实例化其自己的类加载器,否则你实际上并不需要了解更多信息,只需记住此优先级列表。特别是,你应该知道可能存在的任何类名冲突。例如,如果在类路径上列出一个类,如果运行时环境改为加载在安装型扩展中找到的同名的另一个类,则会得到意外的结果。
Java 类加载机制
Java 平台使用委托模型来加载类。基本思想是每个类加载器都有一个“父”类加载器。在加载类时,类加载器首先将对类的搜索“委托”到其父类加载器,然后再尝试查找类本身。
以下是类加载 API 的一些要点:
- java.lang.ClassLoader 中的构造函数及其子类允许你在实例化新的类加载器时指定父级。如果未明确指定父级,则将将虚拟机的系统类加载器指定为默认父级。
- ClassLoader 中的 loadClass 方法在调用加载类时按顺序执行这些任务:
- 如果一个类已经加载了,则返回它。
- 否则,它将搜索新类委托给父类加载器。
- 如果父类加载器未找到该类,则 loadClass 调用方法 findClass 以查找并加载该类。
- 如果父类加载器找不到类,ClassLoader 的 findClass 方法将在当前类加载器中搜索该类。在应用程序中实例化类加载器子类时,你可能希望覆盖此方法。
- 类 java.net.URLClassLoader 用作扩展和其他 JAR 文件的基本类加载器,覆盖 java.lang.ClassLoader 的 findClass 方法搜索一个或多个指定的 URL 以查找类和资源。
要查看使用与 JAR 文件相关的某些 API 的示例应用程序,请参阅本教程中的 Using JAR-related APIs 课程。
类加载和 java 命令
Java 平台的类加载机制反映在 java 命令中。
- 在 java 工具中,-classpath 选项是设置 java.class.path 属性的简便方法。
- -cp 和 -classpath 选项是等效的。
- -jar 选项运行打包在 JAR 文件中的应用程序。有关此选项的说明和示例,请参阅本教程中的 Running JAR-Packaged Software 课程。