官术网_书友最值得收藏!

2.4.4 序列化單例和類型安全的枚舉

在序列化和反序列化時,如果目標對象是唯一的,那么你必須加倍當心,這通常會在實現單例和類型安全的枚舉時發生。

如果你使用Java語言的enum結構,那么你就不必擔心序列化,它能夠正常工作。但是,假設你在維護遺留代碼,其中包含下面這樣的枚舉類型:

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

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

現在,下面的測試:

將失敗。事實上,saved的值是Orientation類型的一個全新的對象,它與任何預定義的常量都不等同。即使構造器是私有的,序列化機制也可以創建新的對象!

為了解決這個問題,你需要定義另外一種稱為readResolve的特殊序列化方法。如果定義了readResolve方法,在對象被序列化之后就會調用它。它必須返回一個對象,而該對象之后會成為readObject的返回值。在上面的情況中,readResolve方法將檢查value域并返回恰當的枚舉常量:

請記住向遺留代碼中所有類型安全的枚舉以及向所有支持單例設計模式的類中添加readResolve方法。

主站蜘蛛池模板: 乌审旗| 汉川市| 崇仁县| 张家界市| 恭城| 容城县| 柳江县| 福州市| 项城市| 朝阳市| 辽宁省| 舒兰市| 杭锦旗| 阿合奇县| 铁力市| 万荣县| 涿鹿县| 大姚县| 泸定县| 新丰县| 诏安县| 商都县| 兴安县| 玉树县| 久治县| 柳河县| 平南县| 宣武区| 虞城县| 河西区| 淳安县| 临武县| 泾源县| 台前县| 都兰县| 木里| 军事| 南汇区| 五河县| 平顺县| 时尚|