Java7引导程序:检查类而不加载? [英] Java7 bootstrap: Checking class without loading?
问题描述
在阅读这个问题的答案时,我想知道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屋!