【问题标题】:classloader in java is a class itself then who will load the classloader class?java中的类加载器本身就是一个类,那么谁来加载类加载器类呢?
【发布时间】:2017-11-16 02:33:22
【问题描述】:

Java 中的ClassLoader 是一个用于在Java 中加载类文件的类。

java.lang.ClassLoader 是一个抽象类

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

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

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

  1. 引导类加载器

  2. 扩展类加载器

  3. 系统类加载器

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

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

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

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

所以这意味着第一个系统类加载器会将请求委托给扩展类加载器,扩展类加载器会将请求委托给引导类加载器,如果找不到,它将搜索类,然后扩展类加载器将搜索类,如果找不到,然后系统类加载器将搜索类,如果找不到则抛出 ClassNotFoundException

JVM 是否总是以 System class loader 开始加载类?

如有错误请指正

【问题讨论】:

    标签: java jvm classloader


    【解决方案1】:

    术语“系统类加载器”用词不当。正如您所说的正确,它负责从类路径的位置加载类,即 application 类。

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

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

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

    所以,JVM 并不总是以“系统类加载器”开头来加载一个类,而只是为了解析它定义的类(或子加载器)的类引用,或者当被显式查询时,比如解析主类时。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多