標籤:執行 執行個體 前端 檔案 class track article csdn font
1、子類在建立執行個體後,類初始化方法會調用父類的初始化方法(除了Java.lang.Object類,因為java.lang.Object類沒有父類),而這種調用會逐級追述,直到java.lang.Object的初始化方法。
這個地方我說的是初始化方法,而不是構造方法,因為構造方法是相對於java來源程式而言,而編譯後的class檔案是初始化方法即" <init>"方法(紅色部分為方法名),初始化方法是由java來源程式的三個部分組成的,一個部分是成員欄位後的直接的初始化語句,例如private int i=0;private Date date=new Date();等等,第二個部分是由初始化塊組成,例如:
Java code
public class Test{ private int i=0;//初始化第一部分 //以下大括弧內為初始化第二部分 { this.i=4; //do something...... } }
第三個部分就是java原始碼中的構造方法中的代碼,java原始碼中有幾個構造方法,那麼class檔案中就有幾個初始化方法,編譯器會把第一部分與第二部分分別複製到每個初始化方法的前端,然後把初始化方法對應參數的構造方法的代碼複製到相應初始化方法中(這裡說的複製其實應該說是編譯,不過為了讓你更好理解所以如此說).
那麼說初始化方法如何追述其父類的,這也關係到初始化方法的結構,初始化方法的執行順序以及結構就如上所說,但是每個初始化方法的第一個執行指令就是調用另外一個初始化方法,這個初始化方法可能是自身類某個初始化方法,例如你的建構函式中第一句有類似this(...)這種語句,那麼初始化方法就會調用自身類的指定構造方法;如果你的構造方法中沒有指定構造方法調用,那麼初始化方法會預設調用父類無參數初始化方法,如果你的子類第一句為 super(....),那麼初始化方法會調用父類指定初始化方法。這種調用過程會遞迴進行調用,直到這個類是java.lang.Object類。
調用初始化方法並不代表會產生對象,你的java代碼中出現new關鍵字加上構造方法的調用,只會產生一個對象,其父類對象不會產生,所以調用父類為抽象類別的構造方法完全是合理的。而且初始化方法對於虛擬機器來說只是一個名稱叫做" <init>"的普通方法,區別只是產生對象以後調用而已(sun 的jdk私人包中有繞過構造方法產生對象的方式,可以證明之上說法,具體如何我這裡不陳述)。
然後回答你的第二個問題,抽象類別中的構造方法其實是用來給繼承的子類來用的,因為構造方法相當於初始化方法,當子類調用構造方法時必須調用父類構造方法,所以你可以在子類產生對象時抽象類別中按需求初始化抽象類別中的欄位以及執行一些初始化代碼。其實並不是一定要產生某個類的執行個體才調用構造方法,子類也需要調用父類構造方法。而產生執行個體也並不一定會調用構造方法,在某些特殊實現中或者特殊情況下,產生執行個體不會調用構造方法。而調用了構造方法也不一定就產生了一個執行個體,但是那一定是一個執行個體調用的,就像一個普通的執行個體方法一樣。
java建立一個子類對象是會調用父類的構造方法會不會建立父類