Java7 Bootstrap : Checking class without loading?

标签 java initialization classloader java-7

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

  • Java Bootstrap 在 JVM 中运行,因此它只能使用标准 JVM 功能(无 native 功能) - 例如,被调用的类必须位于 CLASSPATH 上
  • 标准 JVM 类加载是通过正常的类加载机制完成的(我知道它有几个步骤,我已经使用过类加载器好几次了)
  • 类解析(链接)后,立即运行类初始化(包括初始化静态属性和运行静态初始化器)
  • 无法将前两个步骤分开

我的问题是:

  • 谁在什么阶段调用类初始值设定项? (之前发生了什么,之后发生了什么?)
  • 为什么 Bootstrap 的行为与“正常”类加载不同?除此之外还有更多差异吗?
  • 额外问题:我的哪些假设是错误的?

总结所提到的问题:如果您运行 Java 主类(从 Java7 命令行),它将检查 main() 方法是否存在,而不运行静态初始化程序。在 Java6 中,它的行为有所不同。

最佳答案

可以在不链接的情况下加载类:Java 8 中的启动器通过调用 loadClass 加载主类。类加载器上的方法,它不会链接该类或运行其任何静态方法。

参见http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/sun/launcher/LauncherHelper.java#l495和 java.c#l1221 用于在 Java 8 中加载主类的代码。

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

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

结果 = find_class_from_class_loader(env, sym, true, loader, Protection_domain,true,线程);

调用,在 jdk6/jdk6/hotspot/file/91e5cc5d33b9/src/share/vm/prims/jvm_misc.hpp 中,

jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init, Handle loader, Handle Protection_domain, jboolean throwError, TRAPS);

将 init 设置为 true

关于Java7 Bootstrap : Checking class without loading?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17890723/

相关文章:

Java - 扫描仪类 - 读取文本文件时跳过第一行

c# - C# 中的非初始化变量

apache - apache2 中的初始化模块

java - Jboss类冲突

java - 如何在运行时从下载的 jar 文件加载未知类?

java - 为什么你会想要一个没有在其中声明公共(public)类的 Java 文件?

java - Spring + TestNG 不事务回滚

c# - 变量初始化(C# 和 C++)

java - 如何使用 Google 反射库扫描在运行时加载的 JAR?

java - 单击列表项时崩溃。