2012-02-13 242 views
2

我有一個包含整數foo的序列化對象MyObject。我將值10設置爲整數foo,並使用writeObject()將對象保存到文件中。防止Java序列化設置默認值

我將整數條添加到對象MyObject。我將值15設置爲整數欄,然後使用readObject()加載舊的序列化文件。

舊的可串行化文件不包含整數條,因此整數欄將得到值0.如果舊的可序列化文件不包含變量欄,我想將值15保留在欄中。

我應該重寫readObject()或者我怎樣才能阻止readObject()將「默認值」設置爲未知對象?

我想這樣做是因爲在構造函數中我設置了自己的默認值,並且想使用我自己的默認值來控制版本控制。

回答

1

序列化並未設置默認值,而是將其默認值設置爲Java的默認值初始化方案。

如果我可以總結你的問題。您希望序列化將序列化流中的內容與內存中的值合併。對於Java序列化來說這是不可能的,因爲它控制着要創建的對象。您可以讀取序列化對象,然後手動編寫代碼以合併要合併的字段。如果你堅持使用Java序列化(如果我是你,我會避開它),但是讓我們假設你想繼續使用它。

public class MyObject { 

    public void merge(MyObject that) { 
     // given some other instance of an object merge this with that. 
     // write your code here, and you can figure out the rules for which values win. 
    } 
} 

ObjectInputStream stream = new ObjectInputStream(new FileInputStream(file)); 
MyObject that = stream.readObject(); 
someObject.merge(that); 

中提琴你控制哪些字段將合併到someObject。如果您想讓圖書館爲您合併,請查看http://flexjson.sourceforge.net。它使用JSON序列化,並且使用Beans而不是POJO。但是,有一種方法可以獲取已填充的對象並覆蓋JSON流中的值。這有一些限制。這樣做的另一個好處是你可以在你的對象結構改變了Java序列化在技術上可以做的事情之後,實際上讀取流回來,但是它非常非常困難。

+0

謝謝,這是一個很好的答案。我很高興我沒有被卡住序列化。你會建議什麼?我需要一種將對象存儲爲文件的方式,並對其進行良好的版本控制。 – Mikuz 2012-02-13 20:31:00

+0

如果長期存儲是你的目標,我肯定會說使用類似flexjson的東西。您可以隨時使用任何您需要的對象結構來讀取數據。 Java序列化要困難得多,如果沒有相同的對象和封裝結構,就不可能接近邊界。每當我嘗試使用Java序列化進行長期存儲時,我最終都會將其取出並替換它。 – chubbsondubs 2012-02-13 21:36:19

+0

找到XStream非常有用。 – Mikuz 2012-02-15 22:56:59

0

使用關鍵字transient從序列化/反序列化中排除字段。

+0

我想序列化和反序列化吧。如果bar在反序列化的內容中不存在,我只是不希望應用默認的反序列化值。 – Mikuz 2012-02-13 19:35:54

+0

@ user1207523,然後在'readObject'方法(或'readResolve()')中簡單地實現這樣的邏輯。 – mre 2012-02-13 19:37:16

0

是否將以下方法添加到您的MyObject爲您工作?

private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException 
{ 
    bar = 15; // Set a default value of 15 if it's not in the serialized output file 
    ois.defaultReadObject(); 
} 
+0

不是,它會在閱讀中被覆蓋。雖然這對我有用,因爲酒吧不能爲零。 ois.defaultReadObject();如果(巴== 0)欄= 15;謝謝。不過,我希望我們能爲此找到更好的答案。 – Mikuz 2012-02-13 19:51:28

+0

有趣。我要麼在這裏(非常可能)依靠未定義的行爲,要麼做與你不同的事情。在我的測試中(在將欄添加到我的類之前使用序列化的對象文件),讀取並不覆蓋該值,最終我得到了15。只有當我的序列化對象文件首先包含一個欄時,它纔會覆蓋它。希望你能找到更好的答案。 – spdaley 2012-02-13 20:11:53