Java7引导:在不加载的情况下检查类?

Java7引导:在不加载的情况下检查类?,java,initialization,classloader,java-7,Java,Initialization,Classloader,Java 7,在阅读的答案时,我想知道Java7 bootstrap如何知道存在publicstaticvoidmain(String[]args)方法,而不运行静态初始化器?我对这个话题有一些假设,但其中一些显然是错误的: Java引导程序在JVM中运行,因此它只能使用标准JVM特性(没有本机特性)——例如,被调用的类必须位于类路径上 标准的JVM类加载是通过普通的类加载机制完成的(我知道它有几个步骤,我已经多次使用类加载程序) 解析(链接)类后,立即运行类初始化(包括初始化静态属性和运行静态初始值设定项

在阅读的答案时,我想知道Java7 bootstrap如何知道存在
publicstaticvoidmain(String[]args)
方法,而不运行静态初始化器?我对这个话题有一些假设,但其中一些显然是错误的:

  • Java引导程序在JVM中运行,因此它只能使用标准JVM特性(没有本机特性)——例如,被调用的类必须位于类路径上
  • 标准的JVM类加载是通过普通的类加载机制完成的(我知道它有几个步骤,我已经多次使用类加载程序)
  • 解析(链接)类后,立即运行类初始化(包括初始化静态属性和运行静态初始值设定项)
  • 无法将前两个步骤分开
我的问题是:

  • 谁调用类初始值设定项?在哪个阶段?(之前发生了什么,之后又发生了什么?)
  • 为什么引导行为与“正常”类加载不同?在这个问题上有更多的分歧吗
  • 奖金问题:我的哪一个假设是错误的

总结一下提到的问题:如果运行Java main类(从Java7命令行),它将检查
main()
方法的存在,而不运行静态初始值设定项。在Java6中,它的行为不同。

可以加载一个类而不链接它:Java8中的启动器通过调用classloader上的方法来加载主类,classloader不链接该类或运行其任何静态方法

看到和 java.c#l1221,用于在Java8中加载主类的代码

Java6启动器使用FindClass JNI方法加载主类:我猜这是行为差异的原因。参见jdk6/jdk6/jdk/file/814bf0775b52/src/share/bin/java.c#l1387

FindClass至少在Java 6上初始化该类:jdk6/jdk6/hospot/file/91e5cc5d33b9/src/share/vm/prims/jni.cpp中的实现

result=从类加载器(env、sym、true、loader、,
保护(域,真,线程)

调用jdk6/jdk6/hospot/file/91e5cc5d33b9/src/share/vm/prims/jvm_misc.hpp中的

jclass从类装入器(JNIEnv*env、Symbol*name、jboolean init、句柄装入器、句柄保护域、jboolean抛出器、陷阱)中查找类


如果init为true,则可以在不链接类的情况下加载类:Java 8中的启动器通过调用类加载器上的方法加载主类,而类加载器不链接类或运行其任何静态方法

看到和 java.c#l1221,用于在Java8中加载主类的代码

Java6启动器使用FindClass JNI方法加载主类:我猜这是行为差异的原因。参见jdk6/jdk6/jdk/file/814bf0775b52/src/share/bin/java.c#l1387

FindClass至少在Java 6上初始化该类:jdk6/jdk6/hospot/file/91e5cc5d33b9/src/share/vm/prims/jni.cpp中的实现

result=从类加载器(env、sym、true、loader、,
保护(域,真,线程)

调用jdk6/jdk6/hospot/file/91e5cc5d33b9/src/share/vm/prims/jvm_misc.hpp中的

jclass从类装入器(JNIEnv*env、Symbol*name、jboolean init、句柄装入器、句柄保护域、jboolean抛出器、陷阱)中查找类


当init为true时

不应该,类初始化从未更改。@Phani可能与引导相关-这就是我这样问的原因。它不应该,类初始化从未更改。@Phani可能与引导相关-这就是我这样问的原因。回答很好,谢谢你挖掘这个2年多的老问题!回答得好,谢谢你挖掘这个2年多的问题!