我已經寫了我的Container<T>
類,它將T
項備份到多個集合中 - 主要集合是List<T>
,其他是具有從項目派生的數據的各種映射,主要用於優化搜索。反序列化的對象在所有字段中都爲空
類看起來是這樣的:
class Container<T> implements Serializable {
private static final long serialVersionUID = 1L;
private final List<T> items = Lists.newArrayList();
private final Map<...> map1 = Maps.newHashMap();
private final Map<...> map2 = Maps.newHashMap();
}
標準系列化的作品就像一個魅力,但地圖並不需要被序列化。我試圖設置地圖爲transient
並以這種方式使用readObject()
:
class Container<T> implements Serializable {
private static final long serialVersionUID = 1L;
private final List<T> items = Lists.newArrayList();
private transient Map<...> map1;
private transient Map<...> map2;
public Container() {
initContainer();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initContainer();
}
private void initContainer() {
map1 = Maps.newHashMap();
map2 = Maps.newHashMap();
// prepare data in maps
for (T item: items) {
map1.put(...);
map2.put(...);
}
}
}
簡單測試與ObjectOutputStream.writeObject()
和ObjectInputStream.readObject()
再次工作。但是當我將Container
集成到真正的應用程序中,這個類作爲其他複雜類(Wicket Page實際上)的一部分被序列化和反序列化時,會發生奇怪的事情。
我做了一些調試,這裏是我的發現:
- 的
Container
有(n)的項目序列化方面做的Container
OK - 反序列化方面做OK
- 每個
T
項目的反序列化被稱爲只有(n-1)次(通過計數調用其readObject()
方法) - in
containerInit()
hadList<T>
正確的(n)個項目,但其中一個(一個用於沒有所謂的反序列化)是很奇怪的狀態 - 所有領域都null
價值 - 在這裏我的代碼,拋出NPE
問題:
- 什麼狀態有一個奇怪的物體反序列化後(它是存在的,但沒有
readObject()
調用,並在所有字段中爲空)? - 也許這個奇怪對象的反序列化沒有完成,但我已經讀取
ObjectInputStream
的讀取對象是阻塞的,所以我列表中的所有對象都必須處於正確的狀態。或者我忽略了一些東西? - 是否有任何技術/工具/做法捕捉這樣的事情?
謝謝。
幾個問題:不正確的反序列化對象是否一致?如果是這樣,它的狀態與其他狀態有何不同?此外,無論何時反序列化對象,最好假設它們來自惡意來源,並相應地檢查其狀態,例如空值或任何可能危及應用程序的內容。 – 2010-07-21 14:39:30
在串行化被應用程序中的其他對象引用之前,這個對象在每種情況下都不相同 - 在串行化調用它的writeObject()方法之前,它是完全健康的對象。 我還有一個更重要的發現:事實上,當我不遍歷'Container.readObject()'(或'initContainer()'中的'items'時,一切正常!它看起來像我無法正確觸摸readObject()中的反序列化數據,它必須在序列化完成後推遲。也許它是依賴於序列化開始之前對象的現有引用...非常非常奇怪... – mschayna 2010-07-21 15:48:58