2010-11-03 73 views
4

有很多收藏品不是Serializable。一些特別討厭的是上的keySetvalues集合(參見該討論的JDK bug 47562774501848)。是SerializableWrappers收集一個壞主意?

如果我需要序列化這些集合中的一個,則建議的一個解決方法是在另一個集合中實施Serializable,然後發送它。例如:

Set<T> realSet = myHashMap.keySet(); 
Set<T> toSerialize = new HashSet<T>(realSet); 

我不喜歡這樣的開銷,尤其是當考慮到序列化操作的實現通常是爲寫出的大小,並通過一系列迭代一次一樣簡單。

這使我想到了一個可序列化的包裝類,它實現了這個簡單的序列化表單,並且只有synchronizedSet和朋友的精神,對代表只有一個臨時引用。就像這樣,實現僅取決於size()iterator,並且使用readResolve進行反序列化以給出HashSet,比方說。

這感覺有點髒。真正的漏洞在哪裏?

  • 不能處理基於等價關係到的HashSetTreeSetIdentityHashMap等)的集合。我看不出這個問題太重要了,我們只是沒有在這些類型的集合中指定結果,正如其他地方所見。
  • 有沒有關於版本uid的序列化陷阱,會阻止這個工作?關於嘗試它...
  • 當反序列化時,這不會遵守HashMap#keySet()的規範,因爲它不是映射的實時視圖。是否可以指定它是序列化時映射的靜態視圖?
+0

當你必須序列化Map和keySet的引用時,真正的問題出現了。複製keySet顯然不會使兩個集合保持同步。 – cquezel 2013-11-14 02:41:14

回答

2

我不喜歡這個

過早的優化的開銷。憑藉99%的確定性,使用複製構造函數不會成爲程序中的性能瓶頸。在分析器告訴你什麼是你之前,你甚至不應該開始這種考慮。

+0

這是一個公平點。 – 2010-11-04 08:26:15

1

在類似的情況下,我去與
http://code.google.com/p/protobuf/
這是很容易實現,並有一些眼前的利益。這個想法是,不是直接序列化對象,而是每個對象包裝一條消息,所有消息都是一組變量及其值。然後你序列化消息。要恢復對象,只需將消息傳遞給構造函數並設置其狀態。
的protobuf從重新序列解耦序列化(ERM和語言,您連載中的數據)

在另一方面Java序列化的數據規模而言是荒謬的。 Java對對象包的名稱進行編碼,所以如果你使用像Java一樣的命名空間,應該在Java中com.thisismyobject.manthesecharactersareaddingup嵌入到每個序列化對象的每次傳輸中,所以你說嵌套對象在序列化對象中的大小几乎是其大小的20倍實際有用的數據!

+0

這根本不是一個壞主意,儘管需要在所有客戶端對象上切換到protobuf。不幸的是,我的動機是使用RMI,所以我確實需要正常的序列化。 – 2010-11-04 08:24:44

0

我認爲最好的解決方案是實現一些方法來自己對這些集合進行序列化/反序列化。所以你將會獨立於Java集合框架的變化。

+0

確實。問題是封裝是否是一個明智的想法,或者是否應該在序列化之前堅持將內容複製到另一個集合中。我認爲我們可以假設'HashSet'的序列化形式在不久的將來不會改變...... – 2010-11-04 08:19:15

相關問題