问题
I know that the new, dup, invokespecial and astore bytecode pattern will invoke the instance initializer method <init> when someone instance a Java class from the Java language point of view, but i never figure out who invoke the special <clinit>method and when does this happen?
My guess is that <clinit> is invoked before <init> method. Can any body give me some information to prove it? Is this documented in the JVM Specification or Java Language Specification?
回答1:
JVM spec §2.9. Special Methods:
A class or interface has at most one class or interface initialization method and is initialized (§5.5) by invoking that method. The initialization method of a class or interface has the special name
<clinit>, takes no arguments, and is void (§4.3.3).The name
<clinit>is supplied by a compiler. Because the name is not a valid identifier, it cannot be used directly in a program written in the Java programming language. Class and interface initialization methods are invoked implicitly by the Java Virtual Machine; they are never invoked directly from any Java Virtual Machine instruction, but are invoked only indirectly as part of the class initialization process.
See Chapter 5 for further details on the class initialization process.
回答2:
<clinit> is a static method added by javac and called by JVM after class loading. We can see this method in class bytecode with bytecode outline tools. Note that <clinit> is added only if a class needs static initilization, e.g
public class Test1 {
static int x = 1;
public static void main(String[] args) throws Exception {
}
}
public class Test2 {
static final int x = 1;
public static void main(String[] args) throws Exception {
}
}
Test1 has <clinit> because its field x needs to be initialized with 1; while Test2 has no <clinit> method because its x is a constant.
It's also interesting to note that Class.forName has boolen intialize param which determines if the class should be initialized after loading or not.
回答3:
<clinit> are the static initialization blocks for the class, and static field initialization and its invoked by JVM.
Java Spec says, http://java.sun.com/docs/books/jvms/second_edition/html/Overview.doc.html#12174
The initialization method of a class or interface is static and takes no arguments. It has the special name <clinit>. This name is supplied by a compiler. Because the name <clinit> is not a valid identifier, it cannot be used directly in a program written in the Java programming language. Class and interface initialization methods are invoked implicitly by the Java virtual machine
来源:https://stackoverflow.com/questions/15919317/who-invokes-the-class-initializer-method-clinit-and-when