由於Java中的所有事物都是對象, 所以許多動作就變得更加容易, 載入動作僅僅是其中之一.
Java中每個類的編譯代碼都存在於它自己的獨立的檔案中. 該檔案只在需要使用程式碼時才會被載入. 可以說:"類的代碼在初次使用時才載入". 這通常是指直到類的第一個對象被構建時才發生載入, 但是當訪問static欄位方法時, 其也會發生載入.
初次使用之處也是static初始化發生之處. 所有的static對象和static程式碼片段都會在載入時依程式中的順序(即定義類時的書寫順序)而依次初始化. 當然, 定義為static的東西只會被初始化一次.
/** *//**
* Title: The full process of initialization<br>
* Description: 瞭解包括Inheritance在內的初始化全過程, 以對所發生的一切有個全域性的把握<br>
* Copyright: (c) 2008 Thinking in Java<br>
* Company: Augmentum Inc<br>
* @author Forest He
* @version 1.0
*/
class Insect ...{
private int i = 9;
protected int j;
Insect() ...{
System.out.println("i=" + i + ",j=" + j);
j=37;
}
private static int x1 = print("static Insect.x1.initialized");
public static int print(String s) ...{
System.out.println(s);
return 47;
}
}
class Bettle extends Insect ...{
private int k = print("Bettle.k initialized");
public Bettle() ...{
System.out.println("k=" + k);
System.out.println("j=" + j);
}
private static int x2=print("static Bettle.x2 initialized");
public static void main(String [] args) ...{
System.out.println("Bettle constructor");
Bettle b = new Bettle();
}
}
上例中, 在Beetle上運行Java時, 所發生的第一件事就是試圖訪問Beetle.main()(一個static方法), 於是載入器開始啟動並找出Beetle類的編譯代碼(它被編譯到了一個名為Beetle.class的檔案中). 在對Beetle進行載入的過程中, 編譯器注意到它有一個基類(這是由extends關鍵字得知的), 於是Beetle繼續進行載入(對基類載入). 不管你是否打算產生一個該基類的對象, 這都要發生.
如果該基類還有其自身的基類, 那麼第二個基類就會被載入, 如此類推. 接下來, 根基類中的static初始化(在此例中為Insect)即會被執行, 然後是下一個匯出類, 依次類推. 這種方式很重要, 因為匯出類的static初始化可能會依賴於基類成員能否被正確初始化.
至此為止, 必要的類都已載入完畢, 對象就可以被建立了. 首先, 基類對象中的所有基本類型和對象都會被設為預設值; 然後, 基類Constructor會被調用(自動調用or人工通過super()調用). 在基類Constructor完成之後, 匯出類成員按其次序被初始化, 最後匯出類Constructor執行.