问题
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 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
My questions are:
- Who calls the class initializers and in what phase? (what happens before, and what after?)
- Why does the bootstrap behave differently compared to the "normal" classloading? Are there more differences over this?
- Bonus question: Which of my assumptions is wrong?
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.
回答1:
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.
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.
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 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);
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);
with init as true
来源:https://stackoverflow.com/questions/17890723/java7-bootstrap-checking-class-without-loading