當一個類別被第一次使用時,它需要被類別載入器加載,而載入過程涉及以下兩點:
(1)在載入一個類別時,如果它的父類別還未被加載,那麼其父類別必須先被載入;
(2)當類別載入到記憶體之後,按照在程式碼中的出現順序執行它的靜態資料域和靜態區塊。
2.呼叫一個類別的建構子時,呼叫過程涉及以下三點:
(1)呼叫父類別的建構子
(2)依照在程式碼中出現順序初始化實例資料域和實行;
(2)依照在程式碼中出現順序初始化實例資料域和實施實例區塊;
(3)執行其建構函數體。
理論還是得透過實務來證明的,以下以一個簡單的例子來證明。
/** * * @author Sel * * 2014.3.29 */public class InitializationDemo { public static void main(String[] args) { new InitializationDemo(); } public InitializationDemo() { new B(); } { System.out.println("2. Initialization 的实例块。"); } static { System.out.println("1. Initialization 的静态块。"); } }class A { A() { System.out.println("6. A 的构造函数体。"); } { System.out.println("5. A 的实例块。"); } static { System.out.println("3. A 的静态块。"); } }class B extends A { B() { System.out.println("8. B 的构造函数体。"); } { System.out.println("7. B 的实例块。"); } static { System.out.println("4. B 的静态块。"); } }
上面的範例在類別中各個部分輸出對應的文字,以便從輸出中看出其執行順序。
對應的輸出如下:
1. Initialization 的静态块。 2. Initialization 的实例块。 3. A 的静态块。 4. B 的静态块。 5. A 的实例块。 6. A 的构造函数体。 7. B 的实例块。 8. B 的构造函数体。
由輸出可以看出程式執行的順序如下:
1.首先,要使用Initialization類,則是由Initialization類,所以它的靜態區塊載入1;
2.程式呼叫Initialization的建構函數,所以Initialization類別的實例區塊被執行,於是輸出2;
3.然後,執行Initialization的建構函數體,即new B(),這時因為要使用類別B,所以將其載入;
4.因為類別B的父類別為A,那麼在載入B之前,要先載入A,所以這時候執行A的載入過程,即執行A的靜態區塊,於是輸出3;
5.A加載完之後,這時候就到B加載了,這時執行B的加載過程,即執行B的靜態塊,於是輸出4;
6.加載完成後,這時候按照代碼,執行new B(),即B的建構函數,所以這時又要先呼叫父類A的建構函數,於是這時依序執行A的實例塊和建構函數體,輸出5和6;
7.最後,終於到「真正」執行B的建構函式了(因為之前已經一直在說執行new B(),卻是一直在呼叫其他),於是依序執行B的實例區塊和建構函式體,輸出7和8 。
以上就是關於Java的靜態區塊與實例區塊。的內容,更多相關內容請關注PHP中文網(www.php.cn)!