day10-類成員加載順序

類成員加載順序

class A {
    private static int numA;
    private int numA2;
    
    static {
        System.out.println("A的靜態字段 : " + numA);
        System.out.println("A的靜態代碼塊");
    }
    
    {
        System.out.println("A的成員變量  : " + numA2);
        System.out.println("A的非靜態代碼塊");
    }
 
    public A() {
        System.out.println("A的構造器");
    }
}
 
class B extends A {
    private static int numB;
    private int numB2;
 
    static {
        System.out.println("B的靜態字段 : " + numB);
        System.out.println("B的靜態代碼塊");
    }
    
    {
        System.out.println("B的成員變量 : " + numB2);
        System.out.println("B的非靜態代碼塊");
    }
 
    public B() {
        System.out.println("B的構造器");
    }
}
 
public class Box {
    public static void main(String[] args) {
        A ab = new B();
        System.out.println("---");
        ab = new B();
    }
}

在這裏插入圖片描述
面試的時候遇到了這樣一個問題:

class A {
    private static int numA;
    private int numA2;
    
    static {
        System.out.println("A的靜態字段 : " + numA);
        System.out.println("A的靜態代碼塊");
    }
    
    {
        System.out.println("A的成員變量  : " + numA2);
        System.out.println("A的非靜態代碼塊");
    }
 
    public A() {
        System.out.println("A的構造器");
    }
    
    public A(int n) {
        System.out.println("A的有參構造");
        this.numA2 = n;
    }
}
 
class B extends A {
    private static int numB;
    private int numB2;
 
    static {
        System.out.println("B的靜態字段 : " + numB);
        System.out.println("B的靜態代碼塊");
    }
    
    {
        System.out.println("B的成員變量 : " + numB2);
        System.out.println("B的非靜態代碼塊");
    }
 
    public B() {
        System.out.println("B的構造器");
    }
    
    public B(int n) {
        System.out.println("B的有參構造");
        this.numB2 = n;
    }
}
 
public class ClassLoad {
    public static void main(String[] args) {
        B anotherB = new B(1);// 思考有參構造的輸出結果
    }
}

如上代碼,當調用了子類B的有參構造時,父類的構造器先執行肯定是確定無疑,但是是執行哪個構造器呢?
執行結果如下:
在這裏插入圖片描述
執行結果中可以看到,當調用了子類B的有參構造時,父類A依然是執行了無參構造,也就是說,如果子類構造器中未顯式指定父類構造器,那麼將會默認執行父類的無參構造,此時,如果你重載了一個父類的有參構造而沒有指定無參構造,那麼編譯將不會通過!!

例如錯誤代碼如下:
在這裏插入圖片描述
以上內容感謝作者:https://blog.csdn.net/u014745069/article/details/82655339

結論

父類的靜態字段——>父類靜態代碼塊——>子類靜態字段——>子類靜態代碼塊——>父類成員變量(非靜態字段)——>父類非靜態代碼塊——>父類(無參)構造器——>子類成員變量——>子類非靜態代碼塊——>子類構造器

測試

class A {
    private static A a = new A();

    static {
        System.out.print("static");
    }

    public A() {
        System.out.print("A");
    }
}

public class B extends A {
    public B() {
        System.out.print("B");
    }

    public static void main(String[] args) {
        B b = new B();
    }
}
答案:AstaticAB
class A1 {
    private static A1 a = new A1();

    static {
        System.out.print("static");
    }

    {
        System.out.print("A");
    }
}

public class B1 extends A1 {
    public B1() {
        System.out.print("B");
    }

    public static void main(String[] args) {
        B1 b = new B1();
    }
}

答案:AstaticAB
class A2 {
    public A2() {
        System.out.print("A gouzhao");
    }

    private static A2 a = new A2();

    static {
        System.out.print("static");
    }

    {
        System.out.print("A1");
    }
}

public class B2 extends A2 {
    public B2() {
        System.out.print("B");
    }

    public static void main(String[] args) {
        System.out.println("0000");
        B2 b = new B2();
    }
}
答案:
A1A gouzhaostatic0000
A1A gouzhaoB

main方法是一個特殊的方法,在程序開始運行時,系統會找到main方法所在的那個class文件,然後把main方法的自代碼裝入內存,裝入的過程其實就是初識化這個類的過程,初識化成員變量,初始化static變量,初始化static塊,加載這個類(初始化)過程中如果不在執行的方法中new對象的話是不會執行其對應的構造方法和構造塊的,但是這個題在初始化成員變量時就new對象了所以執行結果爲那樣。在main方法中執行new B2時又去執行了父類A2的構造代碼塊和無參構造方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章