1. 程式人生 > >JAVA-初步認識-第十章-對象的初始化過程

JAVA-初步認識-第十章-對象的初始化過程

兩個 而且 如果 image dos super() 就是 images logs

一.

現在簡單地將內存圖解簡單地串一串,從之前的到現在的全部組合起來講述一下,

技術分享

編譯運行的結果為9,按照我們之前的認識來看,對象先是默認初始化,然後顯示初始化,最後是構造器初始化,這是從我們的DOS結果看出來的(如果構造器初始化在前的話,輸出就是0)。

在繼承的時候,這個順序已經澄清了。

要澄清的話,是這樣的,

技術分享

技術分享

技術分享

編譯的結果第一行是0,我們在創建對象時,在成員變量num默認初始化之後,如果後面進行的是顯示初始化num=9,那麽show()方法打印的應該是9,而不是0,說明顯示初始化沒有這麽快操作。編譯的結果為什麽是這樣,直接解釋過,有了繼承以後,子類裏面有一句隱式的super();這裏在對象進行成員變量默認初始化後,接著進行的是子類的構造函數。子類的構造函數裏面碰到了super();接著就去了父類的構造函數,而父類的構造函數的方法體裏面是show()方法。而show()方法是子類在調用,走的是覆蓋後的方法,所以打印的是子類的show()方法的方法體(為什麽執行父類的方法時,操作的是被子類覆蓋的方法

?),這時,num還沒有被顯示初始化,因此打印的是num=0。因此,顯示初始化是在父類構造函數之後。

技術分享

為什麽到了子類的構造器,num就是9了?說明在super()之後,有顯示初始化。這個問題,我們已經解決過了(為什麽現在又忘記了,說明還是註重的怎麽操作,而是怎麽來的。理解了怎麽來的,也就明白了怎麽操作。)

技術分享

技術分享

本質上是構造器先執行的,後來插入了顯示初始化。但是不可否認的是,構造器先於顯示初始化出現的。(要知道,我們一new對象,構造方法就進棧了。到底是怎麽在構造器裏,啟動顯示初始化的?)

早期我們在談論的時候,好像是構造器後執行的。

二.

接下來再對程序做一個修改,來展現在不同情況下的初始化流程。

技術分享

截圖中的程序裏,存在一個構造代碼塊,這樣該如何進行初始化。

技術分享

編譯結果顯示,構造器在構造函數之前。因此,我們可以得到的結論就是,構造代碼塊在構造器之前先執行。是否真是這樣?

(怎麽在構造代碼塊時,num就已經是9了?)

下面對程序進行擴展(補全子父類來講述整個過程),來講述整個初始化過程。

技術分享

技術分享

技術分享

父類show()方法中的“hehe”是無所謂的,它不運行,因為它被子類覆蓋了。

技術分享

(從主函數中的程序來看,只有一句創建對象。編譯運行的結果全是創建對象過程中出現的)

技術分享

以截圖中的程序來講解初始化的過程,主函數的方法體中只有一個創建對象語句,new Zi();

編譯運行的結果如下,通過結果來仔細分析整個過程的每一步。

技術分享

講解內存圖解離不開cpu內部結構,棧,堆以及方法區,三部分。

一new子對象,就加載子類,子父類就加載進來了。這是繼承體系,所以不光是加載子類,而是連著父類一起進入方法區。

整個過程是這樣的,需要創建子類對象,由於創建的是子類的對象,因此需要加載子類進入方法區,而且這是屬於繼承體系,所以不光是子類進入方法區,父類一樣要進入方法區。子父類中的代碼全部加載進入方法區,方法區是起存儲的作用。先存儲這些程序,然後在棧和堆中調用這些方法區的代碼。

創建對象的過程是這樣的,現是加載子父類,然後在堆中開辟空間,載入成員變量,默認初始化值。接下來的所有步驟都是在初始化過程。先是將子類構造函數載入棧中,子類構造函數中第一句是super(); 這句話就是在調用父類的構造函數,父類中有兩句話,第一句是不涉及任何成員,單純地輸出一個語句。第二句就是使用show()方法(為什麽父類構造函數中,使用的show()方法不是父類的show(),而是子類的show()方法?視頻給出的答案是,這一切都是子類在調用,這是前提,因此,調用show()方法,先是看子類中有沒有,子類中有show()方法,因此使用自己的show()方法。),調用子類show()方法時,需要輸出num,子類對象有num,而且只進行了默認初始化,這樣一來,輸出的就是num=0。上面的一切都是子類構造函數中super()語句,下面截圖中標註了初始化的幾步,super(),顯示初始化,構造代碼塊初始化,以及剩余子類構造函數初始化。

技術分享

借用下面的例子來回憶一下初始化過程,

技術分享

技術分享

本例創建對象時,子父類都有num,要存兩個num進入子類對象。

JAVA-初步認識-第十章-對象的初始化過程