- Java核心技術·卷Ⅱ:高級特性(原書第10版)
- (美)凱S.霍斯特曼
- 495字
- 2020-10-30 18:10:42
2.4.4 序列化單例和類型安全的枚舉
在序列化和反序列化時,如果目標對象是唯一的,那么你必須加倍當心,這通常會在實現單例和類型安全的枚舉時發生。
如果你使用Java語言的enum結構,那么你就不必擔心序列化,它能夠正常工作。但是,假設你在維護遺留代碼,其中包含下面這樣的枚舉類型:


這種風格在枚舉被添加到Java語言中之前是很普遍的。注意,其構造器是私有的。因此,不可能創建出超出Orientation.HORIZONTAL和Orientation.VERTICAL之外的對象。特別是,你可以使用==操作符來測試對象的等同性:

當類型安全的枚舉實現Serializable接口時,你必須牢記存在著一種重要的變化,此時,默認的序列化機制是不適用的。假設我們寫出一個Orientation類型的值,并再次將其讀回:

現在,下面的測試:

將失敗。事實上,saved的值是Orientation類型的一個全新的對象,它與任何預定義的常量都不等同。即使構造器是私有的,序列化機制也可以創建新的對象!
為了解決這個問題,你需要定義另外一種稱為readResolve的特殊序列化方法。如果定義了readResolve方法,在對象被序列化之后就會調用它。它必須返回一個對象,而該對象之后會成為readObject的返回值。在上面的情況中,readResolve方法將檢查value域并返回恰當的枚舉常量:

請記住向遺留代碼中所有類型安全的枚舉以及向所有支持單例設計模式的類中添加readResolve方法。
推薦閱讀
- FuelPHP Application Development Blueprints
- Progressive Web Apps with React
- Cocos2D-X權威指南(第2版)
- Objective-C Memory Management Essentials
- Python Deep Learning
- 軟件項目管理實用教程
- SQL經典實例(第2版)
- Instant Lucene.NET
- Android移動開發案例教程:基于Android Studio開發環境
- 計算機應用基礎教程(Windows 7+Office 2010)
- 現代C:概念剖析和編程實踐
- 算法設計與分析:基于C++編程語言的描述
- C/C++代碼調試的藝術(第2版)
- 軟技能2:軟件開發者職業生涯指南
- micro:bit軟件指南