java - java中的classloader本身就是一个类那么谁来加载classloader类呢?

标签 java jvm classloader

Java中的ClassLoader是Java中用来加载类文件的类。

java.lang.ClassLoader 是一个抽象类

我的问题是这个 java.lang.ClassLoader 类是否与 JVM 的类加载器(1. Bootstrap 类加载器 2. 扩展类加载器 3. 系统类加载器)有任何关系?

或者这个 java.lang.ClassLoader 是一个单独的类,可以用来创建自定义类加载器?

类加载器是 Java 运行时环境的一部分,可将 Java 类动态加载到 Java 虚拟机中。它负责定位库,读取其中的内容并加载库中包含的类当 JVM 启动时,使用三个类加载器

  1. 引导类加载器

  2. 扩展类加载器

  3. 系统类加载器

Bootstrap 类加载器加载核心 java 库。它是用 native 代码编写的。引导类加载器负责将关键的 java 类(如 java.lang.Object 和其他运行时代码)加载到内存中。运行时类打包在 jre/lib/rt.jar 文件中。

扩展类加载器加载扩展目录中的代码。它由 ExtClassLoader 类实现。

系统类加载器在 java.class.path 上找到的代码映射到系统类路径变量。它由 AppClassLoader 类实现。默认情况下,所有用户类都由系统类加载器加载。

Java ClassLoader 是分层的,每当提出加载类的请求时,它都会将它委托(delegate)给它的父类,这样就可以在运行时环境中保持唯一性。如果父类加载器没有找到该类,则类加载器本身会尝试加载该类。

这意味着首先系统类加载器将请求委托(delegate)给扩展类加载器,扩展类加载器将请求委托(delegate)给引导类加载器,如果没有找到,扩展类加载器将搜索类,然后系统类加载器将搜索类,如果找不到则抛出 ClassNotFoundException

JVM 是否总是以 System class loader 启动来加载类?

如果我错了请指正

最佳答案

术语“系统类加载器”用词不当。如您正确所述,它负责从类路径的位置加载类,这些类是应用程序类。

从 Java 8 开始,两者都是 AppClassLoaderExtClassLoader , 是 java.net.URLClassLoader 的子类,它是 java.security.SecureClassLoader 的子类,它是 java.lang.ClassLoader 的子类.所有这些类都由 Bootstrap 加载器加载,解决了先有鸡还是先有蛋的问题。

每个运行时类都有一个定义类加载器。对于那些在启动期间由 Bootstrap 加载器定义的类,定义类加载器是 Bootstrap 加载器。当 JVM 初始化完成并尝试启动应用程序时,应用程序类加载器(又名系统类加载器)将查询主类。 Application 类加载器将遵循标准委托(delegate)模型,首先查询父类,Extension 类加载器也是如此,无论哪个类加载器将创建该类,都将是该类的定义类加载器。

现在,当解析一个类被另一个类引用时或者当Class.forName(String)被调用时,包含引用的类的定义加载器将用于解析该类。因此,当 Application 类加载器加载了您的类时 myapp.foo.Bar它包含对 javax.swing.JButton 的引用,它的定义类加载器,即 Application 类加载器,将被查询该类,遵循委托(delegate)模型以 javax.swing.JButton 结束。由 Bootstrap 加载程序定义。所以 javax.swing.JButton 中的类引用仅通过 Bootstrap 加载程序解析,这意味着 javax.swing.JButton不能包含对您的 myapp.foo.Bar 的引用类,因为它不在范围内。

因此,JVM 并不总是以“系统类加载器”开头来加载类,而是仅用于解析由它定义的类(或子加载器)或当被显式查询时,例如解析主类时。

有第 3 方类加载器不严格遵循双亲委托(delegate)模型,但无论它们如何委托(delegate)以及委托(delegate)给哪个加载器,每个类都会有一个定义加载器(由 getClassLoader() 返回),它将是用于解析类内引用的那个。 JVM 确保一个类中相同的符号名称始终解析为相同的运行时类,无论特定类加载器如何实现查找。

请注意,在 Java 9 中,扩展类加载器已被平台类加载器取代。这个类加载器可能会偏离简单的父委托(delegate),即它可能会委托(delegate)给 Application 类加载器来加载应用程序提供的模块,这些模块取代了平台提供的模块。此外,内置类加载器不是 URLClassLoader 的子类。不再。

关于java - java中的classloader本身就是一个类那么谁来加载classloader类呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47320598/

相关文章:

java - 如何在 Maven 中的清洁包期间保护自动生成的源?

java - 动态增加Java程序的内存

java - Java 垃圾收集器的行为是随时间演变还是受到 JIT 的影响?

用于多个 CPU 和大量内存的 Eclipse 性能调整?

java - BufferedInputStream.read(byte[] b, int off, int len) 可以返回 0 吗?是否有可能导致这种情况的重要的、损坏的 InputStreams?

java - 为什么在使用 PDFBox 时出现此错误 "java.io.IOException: Error: Header doesn' t 包含版本信息?

java - 何时创建自定义类加载器?

java - 是否可以在运行时使用 Java 切换类版本?

java - 强制小程序加载到同一个 JVM 实例中?

java - 虚拟机上的类加载器