1. 程式人生 > >readResolve()方法與序列化

readResolve()方法與序列化

在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, 另這個連結中還有一個更為高階的例子, 如有興趣可去一看.