java細節之類中的靜態塊和非靜態塊的執行情況
阿新 • • 發佈:2018-11-30
這篇文章來源於一道面試題:
請問執行的輸出結果?結果如下: F staticpublic class TestBean extends F{ public TestBean(){ System.out.println("testbean constructor"); } {System.out.println("testbean");} static{System.out.println("testbean static");} public static void main(String[] args) { TestBean tb=new TestBean(); TestBean tb1=new TestBean(); } } class F{ public F(){ System.out.println("F constructor"); } {System.out.println("F");} static{System.out.println("F static");} }
testbean static
F
F constructor
testbean
testbean constructor
F
F constructor
testbean
testbean constructor -------------------------------------------------
現在來理一下他們的執行順序: 點選執行之後,從main()入口方法開始執行: TestBean tb=new TestBean();
(一)、要new一個TestBean,肯定得用類載入器先把.class檔案載入到記憶體。
testbean static (二),類載入完後就開始new物件並進行初始化tb。 這裡有個知識點:不要誤解類的初始化物件就只是呼叫建構函式來賦值。 ------------------------類的初始化--------------------------------------------------------------
一共有三種方式對例項變數(物件)進行初始化:
①定義例項變數時指定初始值
②非靜態初始化塊中對例項變數進行初始化,(就是初始化一次就執行非靜態塊一次)
③構造器中對例項變數進行初始化
當new物件 初始化時,①②要先於③執行。而①②的順序則按照它們在原始碼中定義的順序來執行。
同樣,TestBean繼承自F,所以要先初始化F,再初始化TestBean:
所以輸出: FF constructor
testbean
testbean constructor -----------------------這裡有個疑惑?---------------------------------- 父類的建構函式,是在子類的建構函式的第一行預設呼叫的,那麼父類的建構函式,應該是在子類的非靜態塊之後執行的啊? 與上面的順序就矛盾了。原因,我還不知道,諸君知道的,不妨留言告訴我一聲。不過執行結果是上面一個結果。那麼反推執行順序,就是如上文所說。 ------------------------------------------------------------------------------ (三),再次new物件並初始化tb1 重複上述順序,輸出: F
F constructor
testbean
testbean constructor 不再執行靜態塊,靜態塊只在類載入時執行一次。