Java类链接解析步骤或初始化是否会导致加载其他解析类?

Java类链接解析步骤或初始化是否会导致加载其他解析类?,java,jvm,classloader,Java,Jvm,Classloader,我正在阅读JVM规范文档和JLS,关于java中的类加载机制 以下是我的理解 首先,当要求加载主类时,它 查看类的二进制表示形式是否已被删除 是否已加载,如果未加载,则类加载程序将从中加载类文件 磁盘 联系步骤:核查、准备和解决 初始化 我发现令人困惑的是,在解析和初始化步骤中,如果引用了一个尚未从源代码加载的类,会发生什么?解析或初始化步骤是否暂停,以便由其父类加载器加载类 或者加载、链接和初始化是否延迟到运行时执行使用该引用的实际方法或代码时?说明: 链接一个类或接口需要验证和准备该类或接

我正在阅读JVM规范文档和JLS,关于java中的类加载机制

以下是我的理解

  • 首先,当要求加载主类时,它 查看类的二进制表示形式是否已被删除 是否已加载,如果未加载,则类加载程序将从中加载类文件 磁盘

  • 联系步骤:核查、准备和解决

  • 初始化

  • 我发现令人困惑的是,在解析和初始化步骤中,如果引用了一个尚未从源代码加载的类,会发生什么?解析或初始化步骤是否暂停,以便由其父类加载器加载类

    或者加载、链接和初始化是否延迟到运行时执行使用该引用的实际方法或代码时?

    说明:

    链接一个类或接口需要验证和准备该类或接口、它的直接超类、它的直接超接口以及它的元素类型(如果是数组类型的话)。类或接口中符号引用的解析是链接的可选部分

    因此,当不讨论类的直接超类型时,解析是可选的,可能会延迟

    同一节还包含

    例如,Java虚拟机实现可以选择在使用类或接口时单独解析每个符号引用(“延迟”或“延迟”解析),或者在验证类时一次性解析所有符号引用(“急切”或“静态”解析)。这意味着在某些实现中,在类或接口初始化之后,解析过程可能会继续

    所以这个过程并不总是严格遵循你在问题中展示的图形。相反,该决议可以被视为一个持续的进程

    实际上,对于热点JVM,一些类必须立即得到解析,比如超类。其他类在验证方法的代码时解析,这发生在该JVM第一次执行方法之前

    这不会影响方法代码引用的所有类,但取决于实际的类型使用,例如,HotSpot的验证器将解析类型,以根据实际类型层次结构检查分配的有效性,但如果将类型分配给自身或
    java.lang.Object
    ,则跳过此步骤,也就是说,任务始终有效。因此,某些类型可能只有在第一次实际使用时才能得到解析,例如,当通过
    new
    实例化它们时,或者调用该类型声明的
    静态
    方法时。但这取决于代码的微妙方面。另见或

    可能存在仅在反射数据(如注释或调试属性)中引用的类型,这些类型在运行期间从未解析,但可能在另一个运行中


    但由于这意味着类型的解析延迟到实际需要时,因此也意味着此时操作将停止并等待先决条件类的此过程完成。因此,例如,加载一个类总是意味着解析它的直接超类,如果尚未加载则加载它,这反过来意味着解析该超类的超类,等等。因此,在解决完整的超类层次结构之前,它不会返回。

    JVM也在第5.3节中说明

    如果Java虚拟机在验证期间尝试加载C类 (§5.4.1)或决议(§5.4.3)(但不包括初始化(§5.5)),以及类加载器 用于启动C加载的,抛出ClassNotFoundException实例, 然后Java虚拟机必须抛出NoClassDefFoundError的实例 其原因是ClassNotFoundException的实例。 (这里的一个微妙之处是执行递归类加载以加载超类 作为决议的一部分(§5.3.5,步骤3)。因此,ClassNotFoundException 类加载器未能加载超类的结果必须包装在 NoClassDefFoundError。)

    因此,在类加载的解析阶段确实存在递归