Java7引导程序:检查类而不加载? [英] Java7 bootstrap: Checking class without loading?

查看:124
本文介绍了Java7引导程序:检查类而不加载?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在阅读这个问题的答案时,我想知道Java7引导程序是如何知道 public static void main(String [] args)方法,而不运行静态初始化程序的?我对这个主题有一些假设,但其中一些显然是错误的:

When reading the answer to this question, I was wondering how Java7 bootstrap knows about the presence of public static void main(String[] args) method, without running the static initializers? I have some assumptions on this topic, but some of them is obviously wrong:


  • Java Bootstrap在JVM中运行,所以它只能使用标准的JVM特性(没有本机特性) - 被调用的类必须在CLASSPATH上,例如

  • 标准的JVM类加载是通过普通的类加载机制完成的(我知道它有几个步骤,我已经多次使用类加载器了。)

  • 在解析(链接)类之后,立即运行类初始化(包括初始化静态属性和运行静态初始化程序)。

  • 没有办法分开前两个步骤

  • Java Bootstrap is running in JVM, so it can only use standard JVM features (no native features) - the called class must be on CLASSPATH, for example
  • The standard JVM classloading is done via the normal classloading mechanism (I know it has several steps, I've been playing with classloaders several times)
  • After the class has been resolved (linked), the Class initialization is run immediately (including initializing static attributes and running static initializers)
  • There is no way to part the previous two steps

我的问题是:


  • 谁调用类初始值设定项以及在什么阶段? (之前会发生什么,之​​后会发生什么?)

  • 为什么引导程序与普通类加载相比表现不同?对此有更多的区别吗?

  • 奖金问题:我的哪些假设是错误的?

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

To summarize the referred question: if you run a Java main class (from Java7 command line), it will check the presence of the main() method, without running the static initializers. In Java6 it behaves differently.

推荐答案

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

It is possible to load a class without linking it: the launcher in Java 8 loads the main class by calling the loadClass method on the classloader, which does not link the class or run any of its static methods.

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

See http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/sun/launcher/LauncherHelper.java#l495 and java.c#l1221 for the code that loads the main class in Java 8.

Java 6启动程序使用FindClass JNI方法加载主类:我猜这可以解释行为上的差异。请参阅jdk6 / jdk6 / jdk / file / 814bf0775b52 / src / share / bin / java.c#l1387

The Java 6 launcher uses the FindClass JNI method to load the main class: I'm guessing that this accounts for the difference in behaviour. See 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中的实现

FindClass does initialize the class, at least on Java 6: the implementation in jdk6/jdk6/hotspot/file/91e5cc5d33b9/src/share/vm/prims/jni.cpp

result = find_class_from_class_loader(env, sym,true,loader,
protection_domain,true,thread);

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

calls, in 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

with init as true

这篇关于Java7引导程序:检查类而不加载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆