Java Class Loading Mechanism 类加载机制
三大类加载器执行顺序
当运行时环境需要为应用程序加载新类时,它将在以下位置按顺序查找该类:
- 启动类加载器(Bootstrap ClassLoader):rt.jar 中的运行时类,i18n.jar 中的国际化类以及其他。位于
<JAVA_HOME>\lib
- 扩展类加载器 (Extension ClassLoader):
JRE_HOME/lib/ext
或者java.ext.dirs
系统变量指定的路径 中的 JAR 文件中的类。 - 应用程序类加载器(Application ClassLoader):系统属性
java.class.path
指定的路径上的类,包括 JAR 文件中的类。如果类路径上的 JAR 文件具有带有 Class-Path 属性的清单,则还将搜索由 Class-Path 属性指定的 JAR 文件。默认情况下,java.class.path 属性的值是.,即当前目录。您可以使用-classpath 或-cp 命令行选项或设置 CLASSPATH 环境变量来更改值。命令行选项将覆盖 CLASSPATH 环境变量的设置。
Java 类加载机制
The Java platform uses a delegation model for loading classes. The basic idea is that every class loader has a "parent" class loader. When loading a class, a class loader first "delegates" the search for the class to its parent class loader before attempting to find the class itself.
Java 平台使用委托模型来加载类。基本思想是每个类加载器都有一个“父”类加载器。加载类时,类加载器首先将对类的搜索“委派”给其父类加载器,然后再尝试查找类本身。
以下是类加载 API 的一些要点:
- 实例化新的类加载器时,可以使用 java.lang.ClassLoader 及其子类中的构造函数指定父级。如果您未明确指定父级,则会将虚拟机的系统类加载器指定为默认父级。
- 当被调用以加载类时,ClassLoader 中的 loadClass 方法按顺序执行这些任务:
- 如果已经加载了一个类,它将返回它。
- 否则,它将对新类的搜索委托给父类加载器。
- 如果父类加载器找不到该类,则 loadClass 调用方法 findClass 查找并加载该类。
- 如果父类加载器未找到该类,则 ClassLoader 的 findClass 方法将在当前类加载器中搜索该类。当您在应用程序中实例化类加载器子类时,您可能想重写此方法。
- 类
java.net.URLClassLoader
用作扩展和其他 JAR 文件的基本类加载器,它重写java.lang.ClassLoader
的 findClass 方法以在一个或多个指定的 URL 中搜索类和资源。
class NetworkClassLoader extends ClassLoader {
String host;
int port;
public Class findClass(String name) {
byte[] b = loadClassData(name);
return defineClass(name, b, 0, b.length);
}
private byte[] loadClassData(String name) {
// load the class data from the connection
}
}
验证一下:
public class ClassLoaderTest {
public static void main(String[] args) {
final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println("systemClassLoader: "+systemClassLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2
// $JAVA_HOME/jre/lib/ext/*.jar
// $JAVA_HOME/jre/lib/*.jar
// all classpath jar
ClassLoader parent1 = systemClassLoader.getParent();
System.out.println("parent: "+parent1);// parent: sun.misc.Launcher$ExtClassLoader@61bbe9ba
// $JAVA_HOME/jre/lib/ext/*.jar
ClassLoader parent2 = parent1.getParent();
System.out.println("parent2: "+parent2);// parent2: null -> BootstrapClassLoader
// $JAVA_HOME/jre/lib/*.jar
System.out.println("done");
}
}
类加载和 java 命令
- java 工具中,
-classpath
选项是设置java.class.path
属性的简便方法。-cp
和-classpath
选项等效。 - -jar 选项运行打包在 JAR 文件中的应用程序。
参考
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论