Java 在JVM中加载类时,类的不同部分以什么顺序初始化?

Java 在JVM中加载类时,类的不同部分以什么顺序初始化?,java,class,initialization,classloader,Java,Class,Initialization,Classloader,想象一个Java类,它具有在类中可以找到的大多数特性。例如:它从另一个类继承,实现了几个接口,包括一些“静态最终”常量、一些最终常量、一些静态变量、实例变量、一个静态块、一个未命名的代码块(只是{}中的代码)、构造函数、方法等 当所讨论的类第一次加载到JVM中时,类的各个部分以什么顺序初始化或加载到JVM中?JVM中的调用堆栈在加载时是什么样子的?假设这里只有一个类加载器在工作 这要回到Java的绝对基础/内部,但我还没有找到一篇好文章来解释正确的顺序。关于第12.4节的内容如何?这可以在本节中

想象一个Java类,它具有在类中可以找到的大多数特性。例如:它从另一个类继承,实现了几个接口,包括一些“静态最终”常量、一些最终常量、一些静态变量、实例变量、一个静态块、一个未命名的代码块(只是{}中的代码)、构造函数、方法等

当所讨论的类第一次加载到JVM中时,类的各个部分以什么顺序初始化或加载到JVM中?JVM中的调用堆栈在加载时是什么样子的?假设这里只有一个类加载器在工作


这要回到Java的绝对基础/内部,但我还没有找到一篇好文章来解释正确的顺序。

关于第12.4节的内容如何?

这可以在本节中描述

2.17.4初始化

类的初始化包括:

  • 执行其静态初始值设定项(§2.11)和
  • 类中声明的静态字段(§2.9.2)的初始值设定项
接口初始化包括对接口中声明的字段执行初始化器(§2.13.3.1)

在初始化类或接口之前,必须初始化其直接超类,但不需要初始化由类实现的接口。类似地,在初始化接口之前,不需要初始化接口的超级接口

类或接口类型T将在发生以下情况之一之前立即初始化:

  • T是一个类,并且创建了T的一个实例
  • T是一个类,调用了T的静态方法
  • 使用或指定了一个T的非恒定静态场。常量字段是(显式或隐式)最终和静态字段,并用编译时常量表达式的值初始化。对此类字段的引用必须在编译时解析为编译时常量值的副本,因此使用此类字段不会导致初始化
调用库类中的某些方法(§3.12)也会导致类或接口初始化。有关详细信息,请参阅Java2平台的类库规范(例如,class和包Java.lang.reflect)

这里的目的是一个类型有一组初始值设定项,使其处于一致状态,并且该状态是其他类观察到的第一个状态。静态初始值设定项和类变量初始值设定项是按文本顺序执行的,并且可能不会引用在类中声明的类变量,这些类变量的声明在使用后以文本形式出现,即使这些类变量在范围内。此限制旨在在编译时检测大多数循环初始化或其他格式错误的初始化

在初始化一个类或接口之前,如果它以前没有被初始化过,则初始化它的超类


的更新版本

类或接口的初始化包括执行其类或接口初始化方法()

类或接口只能在以下情况下初始化:

  • 执行引用类或接口(,)的Java虚拟机指令
    new
    getstatic
    putstatic
    、或
    invokestatic

    所有这些指令都通过字段引用或方法引用直接或间接引用类。
    在执行新指令时,如果引用的类或接口尚未初始化,则该类或接口将被初始化。
    执行
    getstatic
    putstatic
    invokestatic
    指令后,如果声明已解析字段或方法的类或接口尚未初始化,则该类或接口将被初始化
  • java.lang.invoke.MethodHandle
    实例的第一次调用,该实例是java虚拟机()解析方法句柄的结果,其类型为2(
    REF\u getStatic
    )、4(
    REF\u putStatic
    )、6(
    REF\u invokeStatic
    )或8(
    REF\u newInvokeSpecial
  • 调用类库()中的某些反射方法,例如,在class
    class
    或包
    java.lang.reflect
  • 它的一个子类的初始化
  • 它被指定为Java虚拟机启动()的初始类
初始化之前,必须链接类或接口,即验证、准备和可选地解析类或接口

因为Java虚拟机是多线程的,所以类或接口的初始化需要仔细的同步,因为其他一些线程可能正试图同时初始化同一个类或接口。
类或接口的初始化也可能作为该类或接口初始化的一部分递归地请求

Java虚拟机的实现负责使用以下过程进行同步和递归初始化。
它假设
对象已经过验证和准备,并且
对象包含表示以下四种情况之一的状态:

  • 对象已验证并准备好,但尚未初始化
  • 这个
    对象正由某个特定线程初始化
  • 对象已完全初始化并准备好使用
  • 这个
    对象可能处于错误状态