Who invokes the class initializer method <clinit> and when?

爷,独闯天下 提交于 2020-06-24 08:35:13

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!