1. 程式人生 > >一個實例來理解類的加載及對象的創建過程

一個實例來理解類的加載及對象的創建過程

過程 vat 優先 變量賦值 end private 執行順序 類的屬性 spa

package com.xsl.test;

class Father{
    
    private int i = test();
    private static int j = method();
    
    static{
        System.out.println("(1)");
    }
    
    Father(){
        System.out.println("(2)");
    }
    
    {
        System.out.println("(3)");
    }
    
    
public int test(){ System.out.println("(4)"); return 1; } public static int method(){ System.out.println("(5)"); return 1; } } public class Son extends Father { private int i = test(); private static int j = method();
static { System.out.println("(6)"); } Son() { System.out.println("(7)"); } { System.out.println("(8)"); } public int test(){ System.out.println("(9)"); return 1; } public static int method(){ System.out.println(
"(10)"); return 1; } public static void main(String[] args) { Son s1 = new Son(); System.out.println(); Son s2 = new Son(); } /**運行結果是 (5) (1) (10) (6) (9) (3) (2) (9) (8) (7) (9) (3) (2) (9) (8) (7) 先加載父類靜態屬性,其中父類的靜態屬性調用父類的靜態方法、再加載父類的靜態代碼塊 [此處分別輸出(5)、(1)] 註意:如果靜態屬性不調用靜態方法的話,靜態方法就不加載,即(5)不會被輸出 再加載子類靜態屬性,其中子類的靜態屬性調用子類的靜態方法、再加載子類的靜態代碼塊 [此處分別輸出(10)、(6)] 註意:如果靜態屬性不調用靜態方法的話,靜態方法就不加載,即(10)不會被輸出 再加載父類的一般屬性,其中屬性i調用的test()方法被子類重寫了,所以父類的屬性i調用子類的test()方法 [此處輸出(9)] 再加載父類的代碼塊、父類的構造方法 [此處分別輸出(3)、(2)] 再加載子類的一般屬性,其中屬性i調用test()方法 [此處輸出(9)] 再加載子類的代碼塊、子類的構造方法[此處分別輸出(8)、(7)] 第二次再new出一個子類的對象時,因為在第一次運行時靜態方法、靜態代碼塊就加載出來了存放在靜態區,程序結束後系統才會釋放,所以在程序運行時不會再加載第二次 給靜態成員變量賦值和靜態代碼塊的先後執行順序是看代碼的先後順序 假設該類是第一次進行實例化。那麽有如下加載順序 靜態總是比非靜態優先,從早到晚的順序是: 靜態代碼塊和靜態成員變量的順序根據代碼位置前後來決定。 代碼塊和成員變量的順序也根據代碼位置來決定 最後才調用構造方法構造方法 */ }

一個實例來理解類的加載及對象的創建過程