JAVA中對(duì)象的創(chuàng)建過(guò)程

在上一篇文章中講述了java對(duì)象的銷毀和垃圾回收器的工作方式,這篇文章將講下java對(duì)象的創(chuàng)建,這對(duì)我們平時(shí)的開(kāi)發(fā)也有一定的幫助。

假如存在一個(gè)名為User的類,User的成員變量有靜態(tài)的和非靜態(tài)的。

1:當(dāng)創(chuàng)建User類的對(duì)象或調(diào)用其靜態(tài)成員變量或靜態(tài)方法時(shí),java編譯器會(huì)先定位User.class

2:java裝載機(jī)ClassLoader加載User.class,此時(shí)會(huì)初始化其靜態(tài)成員變量。因此,靜態(tài)成員變量只會(huì)在Class首次被裝載時(shí)初始化一次

3:通過(guò)new User()創(chuàng)建對(duì)象,此時(shí)會(huì)在堆區(qū)域?yàn)槠浞峙浯鎯?chǔ)空間

4:該存儲(chǔ)空間會(huì)被清零,自動(dòng)為User對(duì)象的成員變量設(shè)置默認(rèn)值(基本類型成員變量,如int會(huì)被賦值0),如果有引用,設(shè)置為null

5:執(zhí)行成員變量的初始化(例如int times = 9)

6:調(diào)用構(gòu)造方法,完成類的完整初始化

還有一點(diǎn)需要注意,就是出現(xiàn)繼承時(shí)的構(gòu)造方法的調(diào)用順序

如果User繼承基類BaseBean,那么在創(chuàng)建User對(duì)象,上述的第4步走完之后,順序會(huì)發(fā)生變化

5:調(diào)用基類BaseBean的構(gòu)造方法

6:執(zhí)行User成員變量的初始化

7:調(diào)用User的構(gòu)造函數(shù)

初始化不當(dāng)會(huì)產(chǎn)生的問(wèn)題

下面這個(gè)程序就是由于構(gòu)造方法初始化不當(dāng)引起問(wèn)題的典型??聪旅鎯蓚€(gè)類的定義:

最后是以上程序的執(zhí)行結(jié)果。

分析:在User對(duì)象分配堆區(qū)域,并對(duì)區(qū)域清零后,此時(shí)成員變量都被賦予了默認(rèn)值,

1:調(diào)用基類構(gòu)造函數(shù),打印BaseBean

2:調(diào)用init()方法,由于基類的此方法被User重寫(xiě),所以此時(shí)調(diào)用User對(duì)象的init()方法,但此時(shí)name變量還未被初始化,只是被賦予了默認(rèn)值而已,因此打印的是User name:null(此處很驚訝,是造成我們要討論的問(wèn)題的原因)

3:完成成員變量初始化和調(diào)用User構(gòu)造函數(shù)

問(wèn)題分析:User子類在未完全初始化的情況下訪問(wèn)其成員變量,造成null的出現(xiàn)

總結(jié)

在定義構(gòu)造函數(shù)時(shí),盡量快速完成初始化,盡量不要調(diào)用其他方法,因?yàn)槟悴恢雷宇愂欠駮?huì)重寫(xiě)被調(diào)用的方法,就像上面的例子,在init()中就會(huì)出現(xiàn)null的情況,如果此時(shí)直接使用name就會(huì)報(bào)空指針。如果非要調(diào)用方法,可以將方法定義為final 或者private(默認(rèn)也會(huì)被final修飾)類型,避免被子類重寫(xiě),產(chǎn)生問(wèn)題。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容