java創建一個子類對象是會調用父類的構造方法會不會創建父類

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私有包中有繞過構造方法生成對象的方式,可以證明之上說法,具體如何我這裏不陳述)。
然後回答你的第二個問題,抽象類中的構造方法其實是用來給繼承的子類來用的,因爲構造方法相當於初始化方法,當子類調用構造方法時必須調用父類構造方法,所以你可以在子類產生對象時抽象類中按需求初始化抽象類中的字段以及執行一些初始化代碼。其實並不是一定要生成某個類的實例才調用構造方法,子類也需要調用父類構造方法。而生成實例也並不一定會調用構造方法,在某些特殊實現中或者特殊情況下,生成實例不會調用構造方法。而調用了構造方法也不一定就生成了一個實例,但是那一定是一個實例調用的,就像一個普通的實例方法一樣。

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