1. 程式人生 > >Java子父類間靜態程式碼塊、構造程式碼塊、構造方法的執行順序

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、在建立子類的例項物件時傳入引數:若子類有帶引數的構造方法,則執行子類的帶引數的構造方法;若子類沒有帶引數的構造方法或者沒有構造方法,則編譯失敗。