2013-02-20 71 views
3

我發現許多線程運行在stackoverflow.com使SingleTon對象可序列化。 也有專家提供了序列化Singleton對象的方法。
我們如何序列化單身?我想我們不能

在我看來,即使我們實現Serializable接口,我們也不能Serialize對象,因爲SingleTon引用變量在同一個類中是靜態的。
而序列化API說我們不能序列化或寫入文件中的靜態引用狀態。
而且我們也不能保存瞬態變量的狀態。
雖然序列化過程(實際寫入過程)靜態和瞬態變量被忽略。
如果我誤解了,請提供寶貴意見。如果我誤解了,有人可以幫助序列化與代碼示例Singleton對象?

+1

你試過實現一個實現Serializable的Singleton嗎? – Achrome 2013-02-20 13:05:16

回答

1

是的,靜態引用不是seralized。這並不意味着您無法獲取靜態引用(單例實例)的值並選擇序列化它。

+0

那麼,在這種情況下,我們可以保存值,而不需要在singleton類中實現Serializable接口。因爲每個複雜對象(例如單例類的對象)都以像Integer,Long,Double,String等原始類型包裝器對象結束,所有這些都使用Serializable接口實現,因此我們可以在單例對象內序列化值。我從你的評論中瞭解到,我們不能將Singleton作爲一個對象序列化。相反,我們必須從中檢索值並將其序列化到文件 – AmitG 2013-02-20 13:18:22

+0

@AmitG - 否,那不是我所說的。你當然可以序列化一個單身作爲一個對象。 – jtahlborn 2013-02-20 14:41:06

2

我認爲你正在混合實現單例的方式和對象序列化的方式。

雖然通常用於實現單例的靜態字段實際上不會作爲序列化實例的一部分被序列化,但實例本身可以絕對被序列化。您只需將其反序列化版本設置回靜態字段,您需要在代碼中手動執行該字段。

P.S.請注意,我並不是說序列化(甚至是實現)單例是一個好主意,我只是說它可以完成。

1

單身人士可以被序列化,在這裏是如何做到這一點的代碼:


import java.io.Serializable; 

public class MySingleton implements Serializable { 

    private MySingleton(String name) { 
     this.name = name; 
    } 

    private static MySingleton mySingleton; 

    private String name; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public static MySingleton getInstance(String name) { 
     if(mySingleton == null) { 
      System.out.println("in if..."); 
      mySingleton = new MySingleton(name); 
     } 

     return mySingleton; 
    } 
} 

,這裏是「主」方法,獲取Singleton類的實例之上,序列化和反序列化它:



public static void main (String[] args) { 

     MySingleton m = MySingleton.getInstance("Akshay"); 

     try { 
      ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D://temp.ser")); 
      oos.writeObject(m); 

      ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D://temp.ser")); 
      MySingleton m2 = (MySingleton) ois.readObject(); 
      System.out.println(m2.getName()); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
     } 

    } 

和輸出是: -

在如果...

Akshay

謝謝。

+2

但是,如果您比較sel化前後物體的哈希碼,它們是不同的。意味着爲Singleton類創建兩個新實例!爲了避免在你的Singleton類中使用readResolve方法,如下所示:'protected Object readResolve(){return 0;}} }' – 2014-04-29 07:50:05

+0

請參閱下面的鏈接以瞭解更多關於readResolve方法的信息:http://docs.oracle.com/javase/7/docs/platform/serialization/spec/input.html#5903 – 2014-04-29 07:57:11