標籤:
class Meal{ public Meal() { System.out.println("Meal()--構造啦!"); }}class Bread{ public Bread() { System.out.println("Bread()--構造啦!"); }}class Cheese{ public Cheese() { System.out.println("Cheese()--構造啦!"); }}class Lettuce{ public Lettuce() { System.out.println("Lettuce()--構造啦!"); }}class Lunch extends Meal{ public Lunch() { System.out.println("Lunch()--構造啦!"); }}class PortableLunch extends Lunch{ public PortableLunch() { System.out.println("PortableLunch()--構造啦!"); }}public class Sandwich extends PortableLunch{ private Bread bread = new Bread(); private Cheese cheese = new Cheese(); private Lettuce lettuce = new Lettuce(); public Sandwich() { System.out.println("Sandwich()--構造啦!"); } public static void main(String[] args) { new Sandwich(); }}
輸出結果如下:
Meal()--構造啦!
Lunch()--構造啦!
PortableLunch()--構造啦!
Bread()--構造啦!
Cheese()--構造啦!
Lettuce()--構造啦!
Sandwich()--構造啦!
再看一例:
class Insect{ private int i = 9; protected int j; public Insect() { System.out.println("i=" + i + " j=" + j); j = 39; } private static int x1 = printInit("static Insect x1"); protected static int printInit(String s) { System.out.println(s); return 47; }}class Beetle extends Insect{ private int k = printInit("Beetle k "); public Beetle() { System.out.println("k=" + k + " j=" + j);//這個j是父類的 j = 25; } private static int x2 = printInit("static Beetle x2"); public static void main(String[] args) { System.out.println("Beetle constructor"); Beetle beetle = new Beetle();
System.out.println();
System.out.println("Beetle constructor2");
Beetle beetle2 = new Beetle();
} }//輸出結果/*static Insect x1static Beetle x2Beetle constructori=9 j=0Beetle k i=47 j=39
Beetle constructor2
i=9 j=0
Beetle k
k=47 j=39
*/
在Beetle上運行java時,所發生的第一件事就是試圖訪問Beetle.main()(一個static方法),於是載入器開始啟動並找出Beetle類的編譯代碼(在名為Beetle.class檔案中)。在對它進行載入的過程中,編譯器注意到它有一個父類(這是由extends得知),於是它繼續載入(父類)。不管你是否打算產生一個該父類的對象,這都要發生(請嘗試將對象建立代碼注釋掉,以便證明這一點)。
如果該父類還有其自身的父類,那麼第二個父類就會被載入,如此類推。接下來,根父類中的static初始化(在本例是Insect)即會被執行,然後是下一個子類,以此類推。這種方式很重要,因為子類的static初始化可能會依賴於父類成員能否被正確初始化。
至此為止,必要的類都已經載入完畢,對象才可以建立了。首先,對象中的所有基本類型都會被設為預設值,對象引用被設為null--這是通過將對象記憶體設為二進位零值而一舉產生的。然後,父類的構造器會被調用。在父類構造器完成之後,執行個體變數按其次序被初始化,最後構造器的其餘部分被執行。
【java in think】構造器的調用順序