Effective Java學習筆記(十)

2021-04-01 10:29:56 字數 1572 閱讀 5676

第5章序列化

19謹慎的實現serializable介面(implement serializable judiciously

實現serializable介面的代價有:當類被發布之後,改變該類的內部實現的靈活性降低了;增加了出錯的可能和安全漏洞;當發布類的新版本時,測試的負擔增大了,因為需要保證新類與舊類是互相可序列化的。

實現serializable介面不是乙個簡單的決策。

被設計用來繼承的類很少實現serializable介面,其它介面也很少繼承它。

對於設計用來被繼承的不可序列化的類,應該考慮提供乙個無引數的建構函式。

內部類應該很少實現serializable介面。而靜態成員類可以實現serializable介面。

20考慮使用自定義的序列化形式(consider using a custom serialized form

不要不經考慮就使用預設的序列化形式。

當乙個物件的物理表示和邏輯內容一致時,可以使用預設的序列化形式。

就算你認為預設的序列化形式是合適的,你也必須提供乙個readobject方法來保證不變性和安全性。

如果所有的域都是transient的,可以不需要呼叫defaultwriteobject方法,但是不推薦這麼做。

21防禦性的編寫readobject方法(write readobject methods defensively

當物件被發序列化的時候,很重要的一點是防禦性的複製任何客戶端不應該擁有的包含物件引用的域。

乙個readobject方法不應該直接或間接的呼叫任何可以被過載的方法。

以下是一些正確編寫readobject方法的建議:

1)  對於必須保持私有的物件引用域,防禦性的複製該域所儲存的物件。

2)  對於有不變性的類,檢查不變性,如果不滿足的話,就丟擲invalidobjectexception。檢查跟在防禦性複製之後。

3)  如果在反序列化之後整個物件圖需要進行驗證,可以使用objectinputvalidation介面。

4)  不在方法中直接或間接的呼叫任何可被過載的方法。

22必要是提供readresolve方法(provide a readresolve method when necessary

任何readobject方法,不論是顯示的還是預設的,都返回的是乙個新建立的例項,而不是類初始化的時候建立的那個例項。

乙個readresolve方法不僅對於單件是必要的,對於任何其它instance-controlled的類也是。

一條經驗規則是如果你編寫乙個沒有公共和保護建構函式的可序列化類,考慮它是否需要乙個readresolve方法。

該readresolve方法的另外乙個作用是可以作為防禦性readobject的替代。

防禦性的readresolve不適合允許包外繼承的類。

該readresolve方法的可訪問性很重要。

在允許繼承的類中,readresolve方法不能替代readobject。

Effective Java 學習筆記 6

及時消除不使用的物件的引用,理論上,帶有記憶體管理的語言是不存在記憶體洩漏的,但是如果對物件的操作不當,也是可能會造成記憶體洩漏.如有乙個stack,其pop函式如下.public object pop if element.length 0 return null return element s...

Effective Java 學習筆記(5)

盡量復用物件,而不是建立新的物件,特別是當乙個物件是immutable 不可改變 的時候。如string物件,string s new string string 千萬不要這樣做,因為這裡實際上建立了兩個物件。要避免出現這樣的情況,1是可以用靜態工廠函式,來解決,如類庫中的boolean.value...

Effective Java 學習筆記 6

及時消除不使用的物件的引用,理論上,帶有記憶體管理的語言是不存在記憶體洩漏的,但是如果對物件的操作不當,也是可能會造成記憶體洩漏.如有乙個stack,其pop函式如下.public object pop if element.length 0 return null return element s...