先說明一下由來吧,下面是同窗的一道筆試題,之前感受對java初始化也是瞭解一二的,結果,看到這題淚奔了,不會。。。上網查,本身添加println,總算是能把本身講明吧了,不知理解的對不對,先記錄下吧,也許之後再看,會發現這真是。。。幼稚java
public class StaticFunction { public static int k = 0; public static StaticFunction t1 = new StaticFunction("t1"); public static StaticFunction t2 = new StaticFunction("t2"); public static StaticFunction t3 = new StaticFunction("t1"); public static int i = print("i"); public static int n = 99; public int j = print("j"); { print("構造塊"); System.out.println("t1:"+t1); System.out.println("t2:"+t2); System.out.println("j:"+j); } static { print("靜態塊"); System.out.println("t1:"+t1); System.out.println("t3:"+t3); System.out.println("t1.t1:"+t1.t1); System.out.println("t2.t1:"+t2.t1); System.out.println("t3.t1:"+t3.t1); System.out.println("t1.t1.t1:"+t1.t1.t1); System.out.println("t1.t2:"+t1.t2); System.out.println("t1.t2.t2:"+t1.t2.t2); System.out.println("t2.t2.t2:"+t2.t1.t2); if(t1 == t3) System.out.println("t1 == t3"); } public StaticFunction(String str) { System.out.println((++k) + ":" + str + " i=" + i + " n=" + n); ++i; ++n; } private static int print(String str) { System.out.println((++k)+":"+str+" i="+i+" n="+n); ++n; return ++i; } public static void main(String[] args) { System.out.println("Start...."); StaticFunction t=new StaticFunction("init"); System.out.println("Over...."); //System.out.println("j:"+j); } }
運行結果如圖:jvm
上面的說結果也是符合jvm加載類的通常步驟:函數
在Java中,類裝載器把一個類裝入Java虛擬機中,要通過三個步驟來完成:裝載、連接和初始化,其中連接又能夠分紅校驗、準備和解析三步,除了解析外,其它步驟是嚴格按照順序完成的,各個步驟的主要工做以下:
裝載:查找和導入類或接口的二進制數據;
連接:執行下面的校驗、準備和解析步驟,其中解析步驟是能夠選擇的;
校驗:檢查導入類或接口的二進制數據的正確性;
準備:給類的靜態變量分配並初始化存儲空間;
解析:將符號引用轉成直接引用;
初始化:激活類的靜態變量的初始化Java代碼和靜態Java代碼塊。
初始化類中屬性是靜態代碼塊的經常使用用途,但只能使用一次。spa
按照上面的,在載入一個類的時候首先要作的是給它的靜態變量分配存儲空間,並設默認值(int等爲0 object等爲null),而後在按照聲明(定義)靜態變量的順序,對其進行賦值。先是k = 0,而後t1 =new StaticFunction("t1");須要注意,一個類只載入一次,其靜態變量是這個類共享的。因此開始執行 public int j = print("j");又由於此時n與i還處於默認值,全部輸出爲0即i = 0; n = 0。接着開始執行構造塊,能夠看到此時t1仍是null,由於尚未執行構造函數,t1尚未初始化完畢,此時也就爲null了,構造塊以後即是構造函數了。還要注意的是如今仍是執行的類中靜態變量的初始化,尚未輪到靜態塊的執行。在t1,t2,n與i初始化以後才能執行static{};t2也是一樣的操做,靜態變量初始化完畢以後開始執行static{}。靜態(類)操做完畢以後,開始main()。。。code