Java子父類間靜態代碼塊、構造代碼塊、構造方法的執行順序


        在學習Java基礎期間,子父類的靜態代碼塊、構造代碼塊、構造方法的執行順序容易混淆,現在通過一段程序來說明它們的執行順序。

一、先看一個簡單的靜態測試程序:

class FatherStaticTest 
{
	static//靜態代碼塊
	{
            System.out.println("執行父類的靜態代碼塊。");
	}
	
	FatherStaticTest()//父類不帶參數的構造方法
	{
            System.out.println("執行父類的不帶參數的構造方法。");
	}
	
	FatherStaticTest(int num)//父類帶參數的構造方法
	{
            System.out.println("執行父類的帶參數的構造方法。");
	}
	
	//構造代碼塊
	{
            System.out.println("執行父類的構造代碼塊。");
	}
}

class SonStaticTest extends FatherStaticTest
{
	static
	{
            System.out.println("執行子類的靜態代碼塊。");
	}
	
	SonStaticTest()
	{
            System.out.println("執行子類的不帶參數的構造方法。");
	}
	
	SonStaticTest(int num)
	{
	    System.out.println("執行子類的帶參數的構造方法。");
	}
	

	{
	    System.out.println("執行子類的構造代碼塊。");
	}

}

class StaticTest
{
	public static void main(String[] args)
	{
	    new SonStaticTest();
	}
}

運行結果:

執行父類的靜態代碼塊。
執行子類的靜態代碼塊。
執行父類的構造代碼塊。
執行父類的不帶參數的構造方法。
執行子類的構造代碼塊。
執行子類的不帶參數的構造方法。

class FatherStaticTest 
{
	static
	{
	    System.out.println("執行父類的靜態代碼塊。");
	}

	FatherStaticTest()
	{
         System.out.println("執行父類的不帶參數的構造方法。");
	}

	FatherStaticTest(int num)
	{
         System.out.println("執行父類的帶參數的構造方法。");
	}

	FatherStaticTest(String str)
	{
         System.out.println("執行父類的帶參數的構造方法。");
	}

	{
		int i = 1;
		int j = 2;
		int sum = (i+j);
		System.out.println("執行父類的構造代碼塊。"+sum);
	}

	{
		int i = 1;
		int j = 2;
		int sum = (i+j);
		System.out.println("執行父類的構造代碼塊。"+sum);
	}

	{
		int m = 3;
		int n = 4;
		int sum = (m+n);
		System.out.println("執行父類的構造代碼塊。"+sum);
	}

}

class SonStaticTest extends FatherStaticTest
{
	static
	{
	    System.out.println("執行子類的靜態代碼塊。");
	}

	SonStaticTest()
	{

         System.out.println("執行子類的不帶參數的構造方法。");
	}

	SonStaticTest(int num)
	{
		super(7);
        System.out.println("執行子類的帶參數的構造方法。");
	}

	SonStaticTest(String str)
	{
		super(7);
        System.out.println("執行子類的帶參數的構造方法。");
	}

	{
		int i = 1;
		int j = 2;
		int sum = (i+j);
		System.out.println("執行子類的構造代碼塊。"+sum);
	}

	{
		int i = 1;
		int j = 2;
		int sum = (i+j);
		System.out.println("執行子類的構造代碼塊。"+sum);
	}

	{
		int m = 3;
		int n = 4;
		int sum = (m+n);
		System.out.println("執行子類的構造代碼塊。"+sum);
	}

}

class StaticTest
{
	public static void main(String[] args)
	{
		
		new SonStaticTest("a");
	}
}


運行結果:

執行父類的靜態代碼塊。
執行子類的靜態代碼塊。
執行父類的構造代碼塊。3
執行父類的構造代碼塊。3
執行父類的構造代碼塊。7
執行父類的帶參數的構造方法。
執行子類的構造代碼塊。3
執行子類的構造代碼塊。3
執行子類的構造代碼塊。7
執行子類的帶參數的構造方法。



二、結論:

1、執行順序:父類的靜態代碼塊--->子類的靜態代碼塊--->父類的構造代碼塊--->父類的構造方法--->子類的構造代碼塊--->子類的構造方法

2、靜態代碼塊隨類的加載而執行,只執行一次,優先於main方法,用於初始化整個類。

3構造代碼塊是給一個類的所有的對象進行初始化,可執行多次。只要對象一建立,就會調用構造代碼塊。構造代碼塊可以重複,可以有多份。

4構造方法是給與之對應的對象進行初始化,有針對性。構造方法要麼帶參數,要麼不帶參數。當類中沒有顯式的構造方法時,jvm會默認執行一個不帶參數的構造方法。同一個類中不能出現兩個或兩個以上相同的構造方法(方法名和參數列表都相同)。

5、在子類的所有構造方法中如果沒有顯式的super語句,則默認第一條語句爲隱式的super語句:super();會訪問父類的不帶參數的構造方法。當父類中只有帶參數的構造方法時,子類必須用顯式的帶參數的super語句訪問父類的構造方法。若顯示的super語句不帶參數,則編譯失敗。當父類中只有顯式的不帶參數的構造方法時,子類必須用顯示的不帶參數的super語句訪問父類的構造方法。否則,編譯失敗。

6在創建子類的實例對象時未傳入參數,若子類只有帶參數的構造方法則編譯失敗。若子類有不帶參數的構造方法,則執行子類的不帶參數的構造方法。若子類沒有構造方法,則執行隱式的不帶參數的構造方法。

7、在創建子類的實例對象時傳入參數:若子類有帶參數的構造方法,則執行子類的帶參數的構造方法;若子類沒有帶參數的構造方法或者沒有構造方法,則編譯失敗。







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章