類的實例化順序:包括 1.父類靜態數據,構造函數,字段;2.子類靜態數據,構造函數,字段等, 當咱們new一個對象的時候,類實例化的順序是怎麼樣的呢?java
OK.仍是上代碼比較實在(我就是個實在的人~~ 哈哈)app
咱們先新建一個父類,裏面包括靜態數據,構造函數,字段,方法等...ide
/** * @author Lee * @// TODO 2018/7/18-13:13 * @description */ public class FatherClazz { int one = 1; int two = getTwo(); // 靜態代碼塊 static { System.out.println("父類靜態代碼塊被實例化了..."); } { int three = 3; System.out.println("FatherOne:" + one + "," + "FatherTwo:" + two + "," + "FatherThree" + three); } // 構造函數 public FatherClazz() { this(4); System.out.println("父類無參構造函數..."); } public FatherClazz(int num) { System.out.println("父類帶參數的構造函數..." + num); } int getTwo() { System.out.println("父類getTwo方法..."); return 2; } public void methodFirst() { System.out.println("Hi,我是methodFirst..."); } }
新建一個ChildClazz繼承FatherClazz~函數
/** * @author Lee * @// TODO 2018/7/18-13:24 * @description */ public class ChildClazz extends FatherClazz { int childOne = 11; int childTwo = getChildTwo(); { int childThree = 33; System.out.println("childOne:" +childOne +"," + "childTwo: " +childTwo + "," + "childThree:" +childThree); } public ChildClazz(){ this(88); System.out.println("childClazz's construct function!"); } public ChildClazz(int num) { System.out.println("childClazz's construct function with variable : " + num); } { System.out.println("childClazz is starting..."); } public int getChildTwo() { System.out.println("Hi, I'm childClazz's getTwo method ..."); return 22; } static { System.out.println("childClazz static code is running ..."); } @Override public void methodFirst() { System.out.println("method is childClazz"); super.methodFirst(); } }
好了,還剩一步,來寫一個main方法測試下測試
/** * @author Lee * @// TODO 2018/7/18-13:33 * @description 測試類的實例化順序 */ public class NewClazz { public static void main(String[] args) { System.out.println("main app is running "); ChildClazz childClazz = new ChildClazz(); childClazz.methodFirst(); } }
走你~~ (因爲截圖不大美觀,我這就複製控制檯的輸出信息了···)this
main app is running 父類靜態代碼塊被實例化了... childClazz static code is running ... 父類getTwo方法... FatherOne:1,FatherTwo:2,FatherThree3 父類帶參數的構造函數...4 父類無參構造函數... Hi, I'm childClazz's getTwo method ... childOne:11,childTwo: 22,childThree:33 childClazz is starting... childClazz's construct function with variable : 88 childClazz's construct function! method is childClazz Hi,我是methodFirst...
OK,來分析下程序輸出的結果: 1,首先會執行類中static代碼塊(無論代碼塊是否在類的開頭仍是末尾處),若是這個類有父類,一樣會優先查找父類中的static代碼塊,而後執行當前類的static。code
2,而後從父類的第一行開始執行,直至代碼末尾處,中間無論是有賦值仍是method調用,都會按順序一一執行(method),普通代碼塊{ }...對象
3,其次是父類的構造函數,執行帶參數或不帶參數的構造函數,依賴於實例化的類的構造函數有沒有super父類的帶參或不帶參的構造函數(能夠把上述ChildClazz構造方法中的this(88)替換成super(88)來測試)。繼承
4,而後會從子類(當前類)的第一行開始執行,直至代碼末尾處,中間無論是有賦值仍是method調用,都會按順序一一執行(method),普通代碼塊{ }...three
5,接着會是子類(當前類)的構造函數,按順序執行。
6,最後是類方法的調用執行,若是子類覆蓋了父類的method,執行時會先執行子類覆蓋的method,method內若是有super.method(),纔會調用父類的同名method,不然不會。
別人總結的:先靜態、先父後子。 先靜態:父靜態 > 子靜態 。優先級:父類 > 子類 , 靜態代碼塊 > 非靜態代碼塊 > 構造函數。