一 clinit靜態方法 類型初始化方法主要是對static變量進行初始化操作,對static域和static代碼塊初始化的邏輯全部封裝在<clinit>方法中。
java.lang.Class.forName(String name, boolean initialize,ClassLoader loader),其中第二個參數就是是否需要初始化。
Java類型初始化過程中對static變量的初始化操作依賴於static域和static代碼塊的前后關系,static域與static代碼塊聲明的位置關系會導致java編譯器生成<clinit>方法字節碼。類型的初始化方法<clinit>只在該類型被加載時才執行,且只執行一次。
二 對象實例化方法<init>:Java對象在被創建時,會進行實例化操作。該部分操作封裝在<init>方法中,並且子類的<init>方法中會首先對父類<init>方法的調用。Java對象實例化過程中對實例域的初始化賦值操作全部在<init>方法中進行,<init>方法顯式的調用父類的<init>方法,實例域的聲明以及實例初始化語句塊同樣的位置關系會影響編譯器生成的<init>方法的字節碼順序,<init>方法以構造方法作為結束。
三 init和clinit區別:
①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> } }
clinit一定優先於init