<clinit>:在jvm第一次加载class文件时调用,包括静态变量初始化语句和静态块的执行

<init>:在实例创建出来的时候调用,包括调用new操作符;调用Class或java.lang.reflect.Constructor对象的newInstance()方法;调用任何现有对象的clone()方法;通过java.io.ObjectInputStream类的getObject()方法反序列化。

 

initclinit区别:

①init和clinit方法执行时机不同

    init是对象构造器方法,也就是说在程序执行 new 一个对象调用该对象类的 constructor 方法时才会执行init方法,而clinit是类构造器方法,也就是在jvm进行类加载—–验证—-解析—–初始化,中的初始化阶段jvm会调用clinit方法。

 

②init和clinit方法执行目的不同

init is the (or one of the) constructor(s) for the instance, and non-static field initialization. 

clinit are the static initialization blocks for the class, and static field initialization. 

上面这两句是Stack Overflow上的解析,很清楚init是instance实例构造器,对非静态变量解析初始化,而clinit是class类构造器对静态变量,静态代码块进行初始化。看看下面的这段程序就很清楚了。

class X {
    static Log log = LogFactory.getLog(); // <clinit

    private int x = 1;   // <init>
  
    X(){
       // <init>
    }

    static {
       // <clinit>
    }
 }