Reading "Thinking in Java" #5
Posted on 2005-01-27 08:58 Blue Kong 閱讀(568) 評(píng)論(0) 編輯 收藏 所屬分類(lèi): Java World//從老家搬篇過(guò)來(lái),看看排版與顯示效果如何。
6. Reusing Classes
Java編譯器并不會(huì)給任何reference產(chǎn)生缺省對(duì)象,這樣就避免了大多數(shù)情況下的不必要的負(fù)擔(dān)。初始化需要的對(duì)象可以在以下地點(diǎn):
1,對(duì)象定義處。由于類(lèi)初始化順序的規(guī)則,這樣做可以保證以此方法初始化的對(duì)象將會(huì)在構(gòu)造函數(shù)被調(diào)用前完成初始化。
2,構(gòu)造函數(shù)內(nèi)部。
3,當(dāng)需要使用該對(duì)象時(shí),這種方式被稱(chēng)為(緩式初始化)lazy initialization。如果一個(gè)對(duì)象并非總是必須,那么這種方式可以減少額外負(fù)擔(dān)。
關(guān)于清理動(dòng)作,要注意的是順序:首先執(zhí)行當(dāng)前類(lèi)的所有清理動(dòng)作(其中次序和生成次序相反),而后再調(diào)用base class的清理函數(shù)。外帶一句,除了內(nèi)存,最好永遠(yuǎn)不要相信垃圾回收機(jī)制。
Final data
Bruce在這部分說(shuō):Java中final修飾對(duì)于基本類(lèi)型和對(duì)象引用(object reference)而言,意義是不同的。用于基本類(lèi)型時(shí),final讓value(數(shù)值)保持不變。用于object reference時(shí),final讓reference保持不變,但對(duì)象本身的內(nèi)容卻是可以更動(dòng)的惡。Java并未提供讓任何對(duì)象保持不變的機(jī)制,雖然可以自己編寫(xiě)具有保持不變效果的class。特別提醒,array也是對(duì)象。
我要說(shuō)的是,我沒(méi)發(fā)現(xiàn)final在基本類(lèi)型與對(duì)象引用的意義有何不同。final都是讓兩者的value保持不變,基本類(lèi)型的value就是對(duì)應(yīng)的數(shù)值或者bool值。而對(duì)象引用的value在理解上可以解釋為指向object的地址。當(dāng)然,這里似乎對(duì)于Java的底層實(shí)現(xiàn)做了假設(shè)而我確實(shí)也沒(méi)細(xì)究過(guò)Java如何實(shí)現(xiàn)object reference的。但是,就Java語(yǔ)法及我個(gè)人的體會(huì)而言,我覺(jué)得這是很好的一種理解方式。
Blank finals
Java允許把數(shù)據(jù)成員聲明為final卻不賦予初始值。當(dāng)然,final修飾的數(shù)據(jù)成員必須在其被使用前完成初始化,這一點(diǎn)由編譯器保證。這個(gè)特性讓我們可以把某個(gè)數(shù)據(jù)成員聲明為final具有不變的特性,卻在每個(gè)對(duì)象中為不同的值。
Final arguments
Java中還可以把method的arguments聲明為final,意義不變,只是不變特性的范圍僅僅在此method內(nèi)。對(duì)于對(duì)象引用,即是在此method內(nèi)擁有此對(duì)象的一個(gè)不可變更的引用,而不影響此對(duì)象存在其他非final的引用。
Final method
有兩個(gè)原因把一個(gè)method修飾成final。第一,對(duì)于類(lèi)A中的某個(gè)method,你希望在類(lèi)A所有子類(lèi)中此方法的表現(xiàn)不變,即此方法不可被覆寫(xiě)(overriding)。第二,處于效率考慮,因?yàn)榫幾g器會(huì)嘗試把不太長(zhǎng)的final method改為inner method。而B(niǎo)ruce Eckel建議我們不要相信編譯器的智商,只在確實(shí)處于設(shè)計(jì)的考慮需要時(shí),才把method修飾為final。
final & private
private的method對(duì)于子類(lèi)是不可見(jiàn)的,自然也無(wú)法覆寫(xiě)(overriding)。似乎,private隱含了final?如果一個(gè)函數(shù)已經(jīng)是private,似乎final修飾與否都無(wú)關(guān)緊要?
首先,這兩個(gè)假設(shè),前者錯(cuò)誤,后者正確。因?yàn)閜rivate的method對(duì)于子類(lèi)是不可見(jiàn)的, 所以對(duì)于子類(lèi)而言如此的函數(shù)就如同是父類(lèi)中的一段普通代碼。如果此時(shí)在子類(lèi)中聲明一個(gè)與父類(lèi)中的private method同名的函數(shù),編譯器是允許的。然而,注意,此時(shí)只是在這個(gè)繼承體系中加入了一個(gè)新函數(shù)而已,并非是一個(gè)覆寫(xiě)。因?yàn)楦矊?xiě)(overriding)的前提是,被覆寫(xiě)的函數(shù)是可見(jiàn),是父類(lèi)的對(duì)外的界面。至于對(duì)private函數(shù)再加final修飾,編譯器是允許的。但毫無(wú)意義,因?yàn)閜rivate的函數(shù)對(duì)于子類(lèi)不可見(jiàn),所以也就無(wú)需聲明是否允許覆寫(xiě)(overriding)。
下面還是貼段代碼來(lái)解釋?zhuān)?


















































































我覺(jué)得Java的編譯器在此處的處理不太合適,容易導(dǎo)致混淆。如果對(duì)于private 與 final修飾做互斥處理,我個(gè)人覺(jué)得會(huì)是比較合適的又容易理解的方式。