實(shí)踐:實(shí)際履行, 尤指藝術(shù). 科學(xué)或技術(shù)領(lǐng)域:與理論遙相對(duì)應(yīng).
Praxis: Practice,especially of an art,science, or technical occupation, opposite to theory.
-Webster''s New Collegiate Dictionary 1958
譯序by侯捷
譯序by劉永丹
細(xì)目 DetailContents
前言preface
致謝 Acknowledgement
1 一般技術(shù)(General Techniques)
實(shí)踐1:參數(shù)以byvalue方式而非by reference方式傳遞
實(shí)踐2:對(duì)不變的data和object reference使用final
實(shí)踐3:缺省情況下所有non-static函數(shù)都可被覆寫(xiě)
實(shí)踐4:在arrays和vectors之間慎重選擇
實(shí)踐5:多態(tài) po1ymorphism 優(yōu)于instanceof
實(shí)踐6:必要時(shí)才使用instanceof
實(shí)踐7:一旦不再需要objectreferences, 就將它設(shè)為nu11
2 對(duì)象與相等性(Objects and Equality)
實(shí)踐8:區(qū)分reference型別和primitive型別
實(shí)踐9:區(qū)分==和equals
實(shí)踐10:不要依賴(lài)equals 的缺省實(shí)現(xiàn)
實(shí)踐11:實(shí)現(xiàn)equals 時(shí)必須深思熟慮
實(shí)踐12:實(shí)現(xiàn)equals 時(shí)優(yōu)先考慮使用getClass
實(shí)踐13:調(diào)用super. equals 以喚起baseclass的相關(guān)行為
實(shí)踐14:在equals 函數(shù)中謹(jǐn)慎使用instanceof
實(shí)踐15:實(shí)現(xiàn)equals 時(shí)需遵循某些規(guī)則
3異常處理(Exception Handling)
實(shí)踐16:認(rèn)識(shí)[異常控制流] exceptioncontrolflow 機(jī)制
實(shí)踐17:絕對(duì)不可輕忽異常 Neverignoreanexception
實(shí)踐18:千萬(wàn)不要遮掩異常 Neverhideanexception
實(shí)踐19:明察throws子句的缺點(diǎn)
實(shí)踐20:細(xì)致而全面地理解throws子句
實(shí)踐21:使用finally避免資源泄漏 resourceleaks
實(shí)踐22:不要從try區(qū)段中返回
實(shí)踐23:將try/catch區(qū)段置于循環(huán)之外
實(shí)踐24:不要將異常 exceptions 用于流程控制
實(shí)踐25:不要每逢出錯(cuò)就使用異常 exceptions
實(shí)踐26:在構(gòu)造函數(shù) constructors 中拋出異常
實(shí)踐27:拋出異常之前先將對(duì)象恢復(fù)為有效狀態(tài) valid state
4 性能(Performance)
實(shí)踐28:先把焦點(diǎn)放在設(shè)計(jì). 數(shù)據(jù)結(jié)構(gòu)和算法身上
實(shí)踐29:不要倚賴(lài)編譯期 compile-time 優(yōu)化技術(shù)
實(shí)踐30:理解運(yùn)行期 mntime 代碼優(yōu)化技術(shù)
實(shí)踐31:如欲進(jìn)行字符串接合, StringBuffer優(yōu)于String
實(shí)踐32:將對(duì)象的創(chuàng)建成本 creationcost 降至最小
實(shí)踐33:慎防未用上的對(duì)象 unusedobjects
實(shí)踐34:將同步化 synchronization 降至最低
實(shí)踐35:盡可能使用stack變量
實(shí)踐36: 使用static. final和private函數(shù)以促成inlining
實(shí)踐37:instance變量的初始化一次就好
實(shí)踐38:使用基本型別 primitivetypes 使代碼更快更小
實(shí)踐39:不要使用Enumeration或Iterator來(lái)遍歷vector
實(shí)踐40:使用System. arraycopy 來(lái)復(fù)制arrays
實(shí)踐41:優(yōu)先使用array, 然后才考慮Vector和ArrayList
實(shí)踐42:盡可能復(fù)用 reuse 對(duì)象
實(shí)踐43:使用緩式評(píng)估 延遲求值, lazyevaluation
實(shí)踐44:以手工方式將代碼優(yōu)化
實(shí)踐45:編譯為本機(jī)代碼 Compile to native code
5 多線(xiàn)程 Multithreading
實(shí)踐46:面對(duì)instance函數(shù), synchronized鎖定的是對(duì)象 objects 而非函數(shù) methods 或代碼 code
實(shí)踐47:弄清楚synchronizedstatics函數(shù)與synchronized instance函數(shù)之間的差異
實(shí)踐48:以[private數(shù)據(jù)十相應(yīng)訪(fǎng)問(wèn)函數(shù) accessor ]替換[public/protected數(shù)據(jù)]
實(shí)踐49:避免無(wú)謂的同步控制
實(shí)踐50:訪(fǎng)問(wèn)共享變量時(shí)請(qǐng)使用synchronized或volatile
實(shí)踐51:在單一操作 singleoperation 中鎖定所有用到的對(duì)象
實(shí)踐52:以固定而全局性的順序取得多個(gè)locks 機(jī)鎖 以避免死鎖
實(shí)踐53:優(yōu)先使用notifyAll 而非notify
實(shí)踐54:針對(duì)wait 和notifyAll 使用旋鎖 spinlocks
實(shí)踐55:使用wait 和notifyAll 替換輪詢(xún)循環(huán) pollingloops
實(shí)踐56:不要對(duì)locked object 上鎖對(duì)象 之object reference重新賦值
實(shí)踐57:不要調(diào)用stop 或suspend
實(shí)踐58:通過(guò)線(xiàn)程 threads 之間的協(xié)作來(lái)中止線(xiàn)程
6 類(lèi)與接口(Classes and Interfaces)
實(shí)踐59:運(yùn)用interfaces支持多重繼承 multipleinheritance
實(shí)踐60:避免interfaces中的函數(shù)發(fā)生沖突
實(shí)踐61:如需提供部分實(shí)現(xiàn) partial implementation 請(qǐng)使用abstract classes 抽象類(lèi)
實(shí)踐62:區(qū)分interface. abstractclass和concreteclass
實(shí)踐63:審慎地定義和實(shí)現(xiàn)immutableclasses 不可變類(lèi)
實(shí)踐64:欲傳遞或接收mutableobjects 可變對(duì)象 之objectreferences時(shí), 請(qǐng)實(shí)施clone
實(shí)踐65:使用繼承 inheritance 或委托 delegation 來(lái)定義immutableclasses 不可變類(lèi)
實(shí)踐66: 實(shí)現(xiàn)clone 時(shí)記得調(diào)用super. clone
實(shí)踐67:別只依賴(lài)finalize 清理non-memory 內(nèi)存以外 的資源
實(shí)踐68:在構(gòu)造函數(shù)內(nèi)調(diào)用non-final函數(shù)時(shí)要當(dāng)心
附錄:如何學(xué)習(xí)Java
進(jìn)階讀物 Further Reading
索引 Index
一般技術(shù)(General Techniques)
實(shí)踐1:引數(shù)是以傳值(by value)而非傳址(by reference)方式傳遞
所有Java objects都透過(guò)object reference而被取用. 常見(jiàn)的一個(gè)誤解是Java以by reference方式傳遞引數(shù). 事實(shí)上所有引數(shù)都以by value方式傳遞.
實(shí)踐2:對(duì)不變的data和object reference使用final
為了讓data或object reference成為不變量, 請(qǐng)使用final. 注意, final僅僅令object reference自身成為不變量, 并不限制它所指向之物件的改變.
實(shí)踐3:預(yù)設(shè)情況下所有non-static函式都可被覆寫(xiě)(overridden)
預(yù)設(shè)情況下, 所有non-static函式都可以被subclass覆寫(xiě). 但如果加上關(guān)鍵字final, 便可防止被subclass覆寫(xiě).
實(shí)踐4:慎重選擇arrays和Vectors
arrays和vectors是常見(jiàn)的容器類(lèi)別(storage classes). 選用它們之前應(yīng)該先了解它們的功用和特性.
實(shí)踐5:多型(polymorphism)優(yōu)於instanceof
instanceof的許多用途可以因?yàn)楦挠枚嘈投? 使用多型, 程式碼將更清晰. 更易於擴(kuò)展和維護(hù).
實(shí)踐6:必要時(shí)才使用instanceof
有時(shí)我們無(wú)法回避使用instanceof. 我們應(yīng)該了解什麼情況下必須使用它.
實(shí)踐7:一旦不再需要object references, 就將它設(shè)為null
不要忽視記憶體可能帶來(lái)的問(wèn)題. 盡管有了垃圾回收機(jī)制(garbage collection), 你仍然需要關(guān)注你的程式碼如何運(yùn)用記憶體. 如果能夠領(lǐng)悟垃圾回收機(jī)制和記憶體運(yùn)用細(xì)節(jié), 你就能夠更好地知道何時(shí)應(yīng)該將object references設(shè)為null, 那將導(dǎo)致高效的程式碼.
物件與相等性(Objects and Equality)
實(shí)踐8:區(qū)分reference type和primitive type
Java是物件導(dǎo)向的, 但其操控的東西并非都是物件(objects). 理解reference type和primitive types之間的差異, 及它們?cè)贘VM中的表述(representation), 會(huì)使你在運(yùn)用它們時(shí)得以做出明智的選擇.
實(shí)踐9:區(qū)分 == 和equals
== 用來(lái)測(cè)試基本型別的相等性, 亦可判定兩個(gè)object references是否指向同一個(gè)object. 若要測(cè)試values(值)或semantic(語(yǔ)意)相等, 應(yīng)使用equals .
實(shí)踐10:不要依賴(lài)equals 的預(yù)設(shè)實(shí)作(default implementation)
不要不假思索地認(rèn)定一個(gè)class總是會(huì)正確實(shí)作出equals . 此外, java.lang.Object提供的equals 大多數(shù)時(shí)候并非進(jìn)行你想要的比較.
實(shí)踐11:實(shí)作equals 時(shí)必須深思熟慮
如果某個(gè)class的兩個(gè)objects「即使不占用相同的記憶體空間, 也被視為邏輯上相等」, 那麼就該為這個(gè)class提供一個(gè)equals .
實(shí)踐12:實(shí)作equals 時(shí)優(yōu)先考慮使用getClass
實(shí)作equals 時(shí)請(qǐng)優(yōu)先考慮采用getClass . 畢竟, 「相同class下的objects才得被視為相等」是正確實(shí)作equals 的一個(gè)清晰簡(jiǎn)明的解決方案.
實(shí)踐13:呼叫base class(基礎(chǔ)類(lèi)別)的super.equals
任何base class(除了java.lang.Object)如果實(shí)作equals , 其derived class都應(yīng)該呼叫super.equals .
實(shí)踐14:在equals 函式中謹(jǐn)慎使用instanceof
唯有當(dāng)你考慮允許「一個(gè)derived class object可以相等於其base class object」時(shí), 才在equals 中使用instanceof. 使用這項(xiàng)技術(shù)前請(qǐng)先弄清楚其影響.
實(shí)踐15:實(shí)作equals 時(shí)需遵循某些規(guī)則
撰寫(xiě)equals 并非那麼直觀淺白. 如果想要恰當(dāng)?shù)貙?shí)作出equals , 請(qǐng)遵循某些規(guī)則.
異常處理(Exception Handling)
實(shí)踐16:認(rèn)識(shí)「異??刂屏鳌梗╡xception control flow)機(jī)制
讓自己諳曉異??刂屏鞒碳?xì)節(jié). 了解這些細(xì)微之處有助於你回避問(wèn)題.
實(shí)踐17:絕對(duì)不可輕忽異常(Never ignore an Exceptions)
一旦異常出現(xiàn)卻沒(méi)有被捕獲, 拋出異常的那個(gè)執(zhí)行緒(thread)就會(huì)中止運(yùn)行. 是的, 異常意味錯(cuò)誤, 永遠(yuǎn)不要忽略它.
實(shí)踐18:千萬(wàn)不要掩蓋異常(Never hide an Exceptions)
如果處理異常期間又從catch或finally區(qū)段拋出異常, 原先的異常會(huì)因而被隱蔽起來(lái). 一旦發(fā)生這樣的事情, 就會(huì)丟失錯(cuò)誤資訊. 你應(yīng)當(dāng)撰寫(xiě)專(zhuān)門(mén)負(fù)責(zé)處理這種情形的程式碼, 將所有異?;貍鹘o呼叫者.
實(shí)踐19:明察throws子句的缺點(diǎn)
將一個(gè)異常加入某函式的throws子句, 會(huì)影響該函式的所有呼叫者.
實(shí)踐20:細(xì)致而全面地理解throws子句
任何函式的throws子句應(yīng)當(dāng)列出它所傳播的所有異常, 包括衍生異常型別(derived exception types).
實(shí)踐21:使用finally避免資源泄漏(resource leaks)
不要忽視記憶體以外的資源. 垃圾回收機(jī)制不會(huì)替你釋放它們. 請(qǐng)使用finally確保記憶體以外的資源被釋放.
實(shí)踐22:不要從try區(qū)塊中回返
不要從try區(qū)塊中發(fā)出return指令, 因?yàn)檫@個(gè)函式未必會(huì)立即從那兒回返. 如果存在finally區(qū)段, 它就會(huì)被執(zhí)行起來(lái)并可能改變回傳值.
實(shí)踐23:將try/catch區(qū)塊置於回圈(loop)之外
撰寫(xiě)含有異常處理的回圈時(shí), 請(qǐng)將try和catch區(qū)塊置於回圈外部. 在某些實(shí)作版本上, 這會(huì)產(chǎn)生更快的執(zhí)行碼.
實(shí)踐24:不要將異常(exceptions)用於流程控制
請(qǐng)將異常用於預(yù)期行為之外的情況. 不要以異常來(lái)控制流程, 請(qǐng)采用標(biāo)準(zhǔn)的語(yǔ)言流程構(gòu)件(flow constructs), 這樣的流程表達(dá)會(huì)更清晰更高效.
實(shí)踐25:不要每逢出錯(cuò)就使用異常(exceptions)
只有面對(duì)程式行為可能出乎預(yù)料的情境下才使用異常. 「預(yù)期中的行為」應(yīng)使用回傳碼(return codes)來(lái)處理.
實(shí)踐26:在建構(gòu)式(constructors)中拋出異常
盡管建構(gòu)式并非函式(method), 因而不能回傳一個(gè)值, 但建構(gòu)式有可能失敗. 如果它們失敗了, 請(qǐng)拋出一個(gè)異常.
實(shí)踐27:拋出異常(exceptions)之前先將object恢復(fù)為有效狀態(tài)
拋出異常很容易, 困難的是「將異常所引發(fā)的傷害減到最小」. 拋出異常之前, 應(yīng)確?!溉绻惓1惶幚砗? 流程再次進(jìn)入拋出異常的那個(gè)函式中, 該函式可以成功完成」.
效能/效率(Performance)
實(shí)踐28:先把焦點(diǎn)放在設(shè)計(jì). 資料結(jié)構(gòu)和演算法身上
給Java帶來(lái)最大效能提升的辦法就是:在設(shè)計(jì)和演算法中使用與語(yǔ)言無(wú)關(guān)的技術(shù). 因此, 首先請(qǐng)將你的精力集中於這些上面.
實(shí)踐29:不要倚賴(lài)編譯期程式碼優(yōu)化技術(shù)
由Java編譯器生成的碼, 通常不會(huì)比你自己撰寫(xiě)的更好. 別指望編譯器能夠多麼優(yōu)化你的原始碼.
實(shí)踐30:理解運(yùn)行期(runtime)程式碼優(yōu)化技術(shù)
Java效能的大部分努力都圍繞著運(yùn)行期優(yōu)化展開(kāi). 這種作法有利有弊.
實(shí)踐31:如欲進(jìn)行字串接合, StringBuffer優(yōu)於String
對(duì)於字串接合, StringBuffer class要比String class快許多倍.
實(shí)踐32:將object的創(chuàng)建成本(creation cost)降至最小
在許多物件導(dǎo)向系統(tǒng)中, 「產(chǎn)生物件」意味著高昂的成本. 了解成本所在, 以及了解「加速物件產(chǎn)生速度」的技術(shù), 都可以導(dǎo)致更快的程式碼.
實(shí)踐33:慎防未用上的物件(unused objects)
非必要?jiǎng)e產(chǎn)生物件. 非必要地產(chǎn)生物件, 會(huì)減慢你的程式速度.
實(shí)踐34:將同步(synchronization)減至最低
宣告synchronized函式或synchronized區(qū)塊, 會(huì)顯著降低效能. 只在物件需要時(shí)才使用同步機(jī)制(synchronization).
實(shí)踐35:盡可能使用stack變數(shù)
stack變數(shù)為JVM提供了更高效的byte code指令序列. 所以在回圈內(nèi)重復(fù)取用static變數(shù)或instance變數(shù)時(shí), 應(yīng)當(dāng)將它們臨時(shí)儲(chǔ)存於stack變數(shù)中, 以便獲得更快的執(zhí)行速度.
實(shí)踐36:使用static. final和private函式以允許實(shí)施inlining
以函式本體替換函式呼叫, 會(huì)導(dǎo)致更快的程式碼. 如果要令函式為inline, 必須先宣告它們?yōu)閟tatic. final或private.
實(shí)踐37:instance變數(shù)的初始化只要一次就好
由於所有static變數(shù)和instance變數(shù)都會(huì)自動(dòng)獲得預(yù)設(shè)值, 所以不必重新將它們?cè)O(shè)為預(yù)設(shè)值.
實(shí)踐38:使用基本型別(primitive types)使程式碼更快更小
使用基本型別, 比使用基本型別外覆類(lèi)別(wrapper), 產(chǎn)生的程式碼又小又快.
實(shí)踐39:不要使用Enumeration或Iterator來(lái)巡訪(fǎng)Vector
巡訪(fǎng)Vector時(shí), 請(qǐng)使用get函式而非Enumeration或Iterator. 這樣做會(huì)導(dǎo)致更少的函式呼叫, 意味程式碼會(huì)更快.
實(shí)踐40:使用System.arraycopy
來(lái)復(fù)制arrays
請(qǐng)使用System.arraycopy
來(lái)復(fù)制arrays. 那是個(gè)原生(native)函式, 速度最快.
實(shí)踐41:優(yōu)先使用array, 然後才考慮Vector和ArrayList
如果可能, 就使用array. 如果你需要Vector的功能但不需要它的同步特性, 可改用ArrayList.
實(shí)踐42:盡可能復(fù)用(reuse)objects
復(fù)用現(xiàn)有物件, 幾乎總是比產(chǎn)生新物件更劃算.
實(shí)踐43:使用緩式評(píng)估(延遲求值, lazy evaluation)
如果某個(gè)成本高貴的計(jì)算并非一定必要, 就盡量少做. 請(qǐng)使用「緩式評(píng)估」
(lazy evaluation, 延遲求值)技術(shù)避免那些永遠(yuǎn)不需要的工作.
實(shí)踐44:手工優(yōu)化(optimize)你的程式碼
由於Java編譯器在優(yōu)化方面的作為甚少, 為了生成最佳byte code, 請(qǐng)手工優(yōu)化你的原始碼.
實(shí)踐45:編譯為原生碼(native code)
編譯為原生碼, 通常可以導(dǎo)致執(zhí)行速度更快的程式碼. 但你卻因此必須在各種不同的原生方案(native solution)中取舍.
多緒(Multithreading)
實(shí)踐46:面對(duì)instance函式, synchronized鎖定的是物件而非函式或程式碼
關(guān)鍵字synchronized鎖定的是物件, 而非函式或程式碼. 一個(gè)函式或程式
區(qū)段被宣告為synchronized, 并不意味同一時(shí)刻只能由一個(gè)執(zhí)行緒執(zhí)行它.
實(shí)踐47:弄清楚synchronized statics與synchronized instance函式之間的差異
兩個(gè)函式被宣告為synchronized, 并不就意味它們是「執(zhí)行緒安全」(thread-safe)的. 對(duì)instance函式或object reference同步化, 與對(duì)static函式或class literal(字面常數(shù))同步化相比, 得到的lock全然不同
實(shí)踐48:以「private資料搭配存取器(accessor)」取代public/protected資料
如果沒(méi)有適當(dāng)保護(hù)你的資料, 用戶(hù)便有機(jī)會(huì)繞過(guò)你的同步機(jī)制.
實(shí)踐49:避免無(wú)謂的同步控制(avoid unnecessary synchronization)
一般情況下請(qǐng)不要同步化所有函式. 同步化不僅造成程式緩慢, 并且喪失了
并行(concurrency)的可能. 請(qǐng)采用「單物件多鎖」技術(shù)以允許更多并行.
實(shí)踐50:取用共享變數(shù)時(shí)請(qǐng)使用synchronized或volatile
不可切割(原子化, atomic)操作并非意味「執(zhí)行緒安全」. JVM實(shí)作品被允許在私有記憶體中保留變數(shù)的工作副本. 這可能會(huì)產(chǎn)生陳舊數(shù)值(stale values). 為避免這個(gè)問(wèn)題, 請(qǐng)使用同步化機(jī)制或?qū)⒆償?shù)宣告為volatile.
實(shí)踐51:在單一操作(single operation)中鎖定所有用到的objects
同步化某一函式, 并不一定就會(huì)使其成為「執(zhí)行緒安全」的函式碼. 如果synchronized函式操控著多個(gè)objects, 而它們并不都是此函式所屬class的private instance data, 那麼你必須對(duì)這些objects自身也進(jìn)行同步化.
實(shí)踐52:以固定而全域性的順序取得多個(gè)locks(機(jī)鎖)以避免死結(jié)(deadlock)
當(dāng)你同步化多個(gè)物件, 請(qǐng)以固定和全域性的順序獲得locks, 以避免死結(jié).
實(shí)踐53:優(yōu)先使用notifyAll 而非notify
notify 只喚醒一個(gè)執(zhí)行緒. 要想喚醒多個(gè)執(zhí)行緒, 請(qǐng)使用notifyAll .
實(shí)踐54:針對(duì)wait 和notifyAll 使用旋鎖(spin locks)
當(dāng)你等待條件變數(shù)(condition variables)時(shí), 請(qǐng)總是使用旋鎖(spin locks)以確保正確結(jié)果.
實(shí)踐55:使用wait 和notifyAll 取代輪詢(xún)回圈(polling loops)
將所有polling loops替換為使用wait . notify 和notifyAll 的spin locks(旋鎖). 使用spin locks直觀而高效, 使用polling loops則慢很多倍.
實(shí)踐56:不要對(duì)locked object(上鎖物件)之object reference重新賦值
當(dāng)一個(gè)object被鎖定, 有可能其他執(zhí)行緒會(huì)因同一個(gè)object lock而受阻(blocked). 假如你對(duì)上鎖物件的object reference重新賦值, 其他執(zhí)行緒中懸而未決的那些locks將不再有意義.
實(shí)踐57:不要呼叫stop 或suspend
不要呼叫stop 或suspend , 因?yàn)樗鼈兛赡軐?dǎo)致資料內(nèi)部混亂, 甚至引發(fā)死結(jié)(deadlock).
實(shí)踐58:透過(guò)執(zhí)行緒(threads)之間的合作來(lái)中止執(zhí)行緒
你不應(yīng)該呼叫stop . 如欲安全地停止執(zhí)行緒, 必須要求它們相互協(xié)作, 才能姿態(tài)優(yōu)雅地中止.
類(lèi)別與介面(Classes and Interfaces)
實(shí)踐59:使用interface支援多重繼承(multiple inheritance)
當(dāng)你想要支援interface的單一繼承或多重繼承, 或者想要實(shí)作一個(gè)標(biāo)記式的(marker)interface時(shí), 請(qǐng)使用interfaces.
實(shí)踐60:避免interfaces中的函式發(fā)生沖突
沒(méi)有任何辦法能夠阻止兩個(gè)interfaces使用同名的常數(shù)和函式. 為了避免可能的沖突, 應(yīng)當(dāng)小心命名常數(shù)和函式.
實(shí)踐61:需要提供部分實(shí)作(partial implementation)時(shí), 請(qǐng)使用abstract classes
使用abstract class來(lái)為一個(gè)class提供部分實(shí)作, 這些實(shí)作很可能對(duì)derived class是共通的(都被需要的).
實(shí)踐62:區(qū)分interface. abstract class和concrete class
一旦正確理解了interface. abstract class和concrete class的差異, 你就可以在設(shè)計(jì)和撰碼時(shí)做出正確的選擇.
實(shí)踐63:審慎地定義和實(shí)作immutable classes(恒常類(lèi)別)
如果你希望object的資料永遠(yuǎn)不被改動(dòng), 請(qǐng)使用immutable object. 這種objects自動(dòng)擁有執(zhí)行緒安全性(thread safety).
實(shí)踐64:欲傳遞或接收mutable objects(可變物件)之object references時(shí), 請(qǐng)施行clone
為了保證immutable objects, 你必須在傳入和回傳immutable objects時(shí)對(duì)它們進(jìn)行clone動(dòng)作.
實(shí)踐65:使用繼承(inheritance)或委托(delegation)來(lái)定義 immutable classes(恒常類(lèi)別)
使用immutable interface. common interface或base class, 或是immutable delegation classes, 來(lái)定義immutable classes(恒常類(lèi)別).
實(shí)踐66:實(shí)作clone 時(shí)記得呼叫super.clone
當(dāng)你實(shí)作了一個(gè)clone , 總是應(yīng)該呼叫super.clone 以確保產(chǎn)生正確的object.
實(shí)踐67:別只是倚賴(lài)finalize 清理記憶體以外的(non-memory)資源
你不能保證finalize 是否被呼叫, 以及何時(shí)被呼叫. 因此, 請(qǐng)專(zhuān)門(mén)實(shí)作一個(gè)public函式來(lái)釋放記憶體以外的資源.
實(shí)踐68:在建構(gòu)式(constructors)內(nèi)呼叫non-final函式時(shí)要當(dāng)心
如果一個(gè)non-final函式被某個(gè)derived class覆寫(xiě), 在建構(gòu)式中呼叫這個(gè)函式可能會(huì)導(dǎo)致不可預(yù)期的結(jié)果.