1. 程式人生 > >Java繼承與初始化

Java繼承與初始化

         在Java中,每一個類的編譯程式碼都存在於它自己的獨立檔案中。該檔案只有在需要時才會被載入,一般是在類初次使用時載入,這通常是指建立類的第一個物件或者第一次訪問類中的靜態方法或者靜態塊。

當JVM要載入一個類A時,如果發現這個類有父類B,那麼JVM首先載入其父類B,如果這個父類B還有其自身的父類C,那麼首先載入類C,一次類推。這個過程是必須要進行的,即使我們有沒有建立類A的物件。看下面這段程式碼,執行之後的輸出結果為,在這段程式碼中,main函式中並沒有任何語句,但是卻產生了輸出,這是因為在執行這段程式碼的時候,第一件事是試圖訪問B.main函式(由於main函式是屬於類B的一個靜態函式,根據上述內容,這時候需要載入類B的編譯程式碼),於是載入器啟動,並找出類B的編譯程式碼(在名為B.class的檔案中),在載入的過程中,發現它繼承與類A,於是轉而先載入類A。在類的載入過程中,載入器會對類的static 變數進行初始化,載入類中的靜態塊。

package testOOP;
class A{
	static{
		System.out.println("this is father's static");
	}
	A(){
		System.out.println("this is father");
	}
	
}
public class B extends A{
	static{
		System.out.println("this is child's static");
	}
	B(){
		System.out.println("this is child");
	}
	public static void main(String [] args){
		
	}
}
在上述的程式碼中,如果main函式中有明確建立B物件的語句,並且類A,和類B都有自己的成員變數和非靜態初始化塊時,類A,類B的初始化順序是怎麼樣的呢?我們首先看一下這段程式碼,執行後的輸出為。根據輸出我們可以看出,在建立類B的物件時,首先會載入父類A,然後載入類B,載入完這兩個類之後,開始進行初始化操作:首先執行父類的非靜態塊的初始化操作,然後執行父類的構造方法,再執行子類的非靜態塊初始化操作,最後執行子類的構造方法。
package testOOP;
class A{
	static{
		System.out.println("this is father's static");
	}
	{
		System.out.println("這是父類的非靜態初始化塊");
	}
	A(){
		System.out.println("this is father");
	}
	
}
public class B extends A{
	static{
		System.out.println("this is child's static");
	}
	{
		System.out.println("這是子類的非靜態初始化塊");
	}
	B(){
		System.out.println("this is child");
	}
	public static void main(String [] args){
		new B();
	}
}
由上述分析內容可以知道,當需要建立一個類A的物件時,其執行順序是:1、載入父類,2、載入類A,3、執行父類的非靜態初始化塊,4、執行父類的構造方法,5、執行子類的非靜態初始化塊,6、執行子類的構造方法。