Java面試基礎篇——第五篇:類的實例化順序

類的實例化順序:包括 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,不然不會。

別人總結的:先靜態、先父後子。 先靜態:父靜態 > 子靜態 。優先級:父類 > 子類 , 靜態代碼塊 > 非靜態代碼塊 > 構造函數。

相關文章
相關標籤/搜索