from:http://lehsyh.javaeye.com/blog/569674
修正了原文的一點錯誤
class Parent {
static String name = "hello";
static {
System.out.println("parent static block");
}
{
System.out.println("parent block");
}
public Parent() {
System.out.println("parent constructor");
}
}
class Child extends Parent {
static String childName = "hello";
static {
System.out.println("child static block");
}
{
System.out.println("child block");
}
public Child() {
System.out.println("child constructor");
}
}
public class StaticIniBlockOrderTest {
public static void main(String[] args) {
new Child();//語句(*)
}
}
Q:當執行完語句(*)時,列印結果是什麼順序?為什嗎?
A:當執行完語句(*)時,列印結果是這樣一個順序:parent static block,child static block,parent block,parent constructor,child block,child constructor。
對象的初始化順序:
父類Static->子類static->父類預設{}->父類建構函式->子類預設{}->子類建構函式
首先執行父類靜態內容,父類靜態內容執行完畢後,接著去執行子類的靜態內容,當子類的靜態內容執行完畢之後,再去看父類有沒有非靜態代碼塊,如果有就執行父類的非靜態代碼塊,父類的非靜態代碼塊執行完畢,接著執行父類的構造方法;父類的構造方法執行完畢之後,它接著去看子類有沒有非靜態代碼塊,如果有就執行子類的非靜態代碼塊。子類的非靜態代碼塊執行完畢再去執行子類的構造方法。
總之一句話,靜態代碼塊內容先執行,接著執行父類非靜態代碼塊和構造方法,然後執行子類非靜態代碼塊和構造方法。
注意:子類的構造方法,不管這個構造方法帶不帶參數,預設的它都會先去尋找父類的不帶參數的構造方法。如果父類沒有不帶參數的構造方法,那麼子類必須用super關鍵子來調用父類帶參數的構造方法,否則編譯不能通過。
PS:
1)、在靜態方法裡只能直接調用同類中其他的靜態成員(包括變數和方法),而不能直接存取類中的非靜態成員。
2)、靜態變數是屬於整個類的變數而不是屬於某個對象的。注意不能把方法體內的任何變數聲明為靜態。
3)、當類被載入時,靜態代碼塊被執行,且only被執行一次,靜態塊常用來執行類屬性的初始化。例如:
static
{
}