内容參考《瘋狂Java程式員的基本修養》李剛 著
一、結論
當調用某個類的構造器來建立Java對象時,系統總會先調用父類的非靜态初始化塊進行初始化,這個調用是隐式的。接着會調用父類的一個或多個構造器執行初始化,這個調用即可通過 super 顯示調用,也可隐式調用。
假設有如下繼承關系:
則構造器的執行順序為:
1、執行Object類的非靜态初始化塊;
2、隐式或顯式調用Object類的一個或多個構造器執行初始化;
3、執行Parent累的非靜态初始化塊;
4、隐式或顯式調用Parent類的一個或多個構造器執行初始化;
5、執行Mid累的非靜态初始化塊;
6、隐式或顯式調用Mid類的一個或多個構造器執行初始化;
7、執行Sub累的非靜态初始化塊;
8、隐式或顯式調用Sub類的一個或多個構造器執行初始化;
二、代碼驗證
代碼為:
Parent類:
package com.tide.controller;
/**
* Created by wengliemiao on 16/3/26.
*/
public class Parent {
public Parent() {
System.out.println("Parent 類無參構造器");
}
public Parent(String name) {
this();
System.out.println("Parent 類帶一個參數構造器, name 參數為: " + name);
System.out.println();
}
{
System.out.println("Parent 類非靜态初始化塊");
}
}
Mid 類:
package com.tide.controller;
/**
* Created by wengliemiao on 16/3/31.
*/
public class Mid extends Parent {
public Mid() {
System.out.println("Mid 類無參構造器");
}
public Mid(String name) {
super(name);
System.out.println("Mid 類帶一個參數構造器, name 參數: " + name);
}
public Mid(String name, int age) {
this(name);
System.out.println("Mid 類帶兩個參數構造器, age: " + age);
System.out.println();
}
{
System.out.println("Mid 類非靜态初始化塊");
}
}
Sub 類:
package com.tide.controller;
/**
* Created by wengliemiao on 16/3/26.
*/
public class Sub extends Mid {
public Sub() {
super("哈哈哈", );
System.out.println("Sub 類無參構造器");
}
public Sub(int a) {
this();
System.out.println("Sub 類帶一個參數構造器, a: " + a);
System.out.println();
}
{
System.out.println("Sub 類非靜态初始化塊");
}
public static void main(String[] args) {
new Sub();
}
}
輸出結果:
是以執行順序為:
1、父類的非靜态初始化塊,構造器;
2、本類的非靜态初始化塊,構造器。
注:
1. super用于顯示調用父類的構造器,this用于顯示調用本類中另一個重載的構造器;
2. super 調用和this 調用都隻能在構造器中使用,并且都必須作為構造器的第一行代碼;
3. super 調用和 this 調用最多隻能使用其中之一, 而且最多隻能調用一次。