先說一下,java程序在執行過程中類大致經過加載、連接、初始化、使用和卸載的五個階段。
和本題目相關的階段有:
類加載階段:查找類文件和導入類或接口的二進制數據;
鏈接:給類的靜態變量分配并初始化存儲空間等;
初始化:執行類的靜態變量的初始化,執行靜態Java代碼塊。靜態代碼塊只執行一次。
(類的非靜態代碼則在類的使用階段(也就是實例化一個類的時候)才會被初始化)
使用:就是在堆中創建對象,構造函數在這個階段。
靜態變量:可以理解為類變量,對應于靜態方法理解為類方法
靜態變量按類型分2種情況:
1.如果靜態變量是基本數據類型,變量放在方法區,在加載類的時候初始化。
2.如果靜態變量是引用類型。則必須先初始化這個類對象之后才能將引用指向它。變量也放在方法區。
靜態代碼塊:靜態代碼塊主要用于類的初始化。在類被加載時自動執行。它只執行一次,并在main函數之前執行。
靜態方法:就是類方法。靜態方法可以直接“類名.方法名”的方式使用,而實例方法必須在類實例化對象后通過“對象名.方法名”來調用。
而對于靜態變量、靜態塊、構造函數、實例變量的執行順序是怎么樣的?
下面看個例子:
注意第4行。
先直接說答案,過程是這樣的:
初始化父類的靜態代碼塊--->初始化子類的靜態代碼塊-->初始化父類的非靜態代碼塊--->初始化父類構造函數--->初始化子類非靜態代碼--->初始化子類構造函數
分步驟:
1,在new Dog(5)進行實例化Dog類時首先要進行類的裝載。
2,在裝載Dog類時,先裝載父類Animal,再裝載子類Dog
3,裝載父類Animal后,完成靜態動作(包括靜態代碼塊和變量,它們的級別是相同的,順序初始化)
4,裝載子類Dog后,完成靜態動作
類裝載完成,開始進行實例化對象:
1,在實例化子類Dog時,先要實例化父類Animal
2,實例化父類Animal時,先成員變量、塊執行
3,父類Animal的構造方法
4,子類Dog的實例化,先成員變量、塊執行
5,子類Dog的構造方法
注意:
第2和第3行是Dog靜態變量部分
第5-9行是Animal實例化時的輸出
第8行和第12行,就是多態的結果。
第10-13行是Dog實例化時的輸出