readResolve()方法與序列化
阿新 • • 發佈:2019-02-08
在CJC(一) 中提到一個問題,即 readResolve方法是幹啥的? 當時也沒多想, 只是列在那裡, 今天忙裡偷閒地把搜點材料整理下這個問題.
原來這個方法跟物件的序列化相關(這樣倒是解釋了為什麼 readResolve方法是private修飾的). ??? 怎麼跟物件的序列化相關了?
下面我們先簡要地回顧下物件的序列化. 一般來說, 一個類實現了 Serializable介面, 我們就可以把它往記憶體地寫再從記憶體裡讀出而”組裝”成一個跟原來一模一樣的物件. 不過當序列化遇到單例時,這裡邊就有了個問題: 從記憶體讀出而組裝的物件破壞了單例的規則. 單例是要求一個JVM中只有一個類物件的, 而現在通過反序列化,一個新的物件克隆了出來.
如下例所示:
Java程式碼
public final class MySingleton implements Serializable {
private MySingleton() { }
private static final MySingleton INSTANCE = new MySingleton();
public static MySingleton getInstance() { return INSTANCE; }
}
public final class MySingleton implements Serializable {
private MySingleton() { }
private static final MySingleton INSTANCE = new MySingleton();
public static MySingleton getInstance() { return INSTANCE; }
}
當把 MySingleton物件(通過getInstance方法獲得的那個單例物件)序列化後再從記憶體中讀出時, 就有一個全新但跟原來一樣的MySingleton物件存在了. 那怎麼來維護單例模式呢?這就要用到readResolve方法了. 如下所示:
Java程式碼
public final class MySingleton implements Serializable{
private MySingleton() { }
private static final MySingleton INSTANCE = new MySingleton();
public static MySingleton getInstance() { return INSTANCE; }
private Object readResolve() throws ObjectStreamException {
// instead of the object we're on,
// return the class variable INSTANCE
return INSTANCE;
}
}
public final class MySingleton implements Serializable{
private MySingleton() { }
private static final MySingleton INSTANCE = new MySingleton();
public static MySingleton getInstance() { return INSTANCE; }
private Object readResolve() throws ObjectStreamException {
// instead of the object we're on,
// return the class variable INSTANCE
return INSTANCE;
}
}
這樣當JVM從記憶體中反序列化地”組裝”一個新物件時,就會自動呼叫這個 readResolve方法來返回我們指定好的物件了, 單例規則也就得到了保證.上面用的例子來源於這個連結:http://www.javalobby.org/java/forums/t17491.html, 另這個連結中還有一個更為高階的例子, 如有興趣可去一看.