2010-07-21 300 views
3

我已經寫了我的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() had List<T>正確的(n)個項目,但其中一個(一個用於沒有所謂的反序列化)是很奇怪的狀態 - 所有領域都null價值 - 在這裏我的代碼,拋出NPE

問題:

  • 什麼狀態有一個奇怪的物體反序列化後(它是存在的,但沒有readObject()調用,並在所有字段中爲空)?
  • 也許這個奇怪對象的反序列化沒有完成,但我已經讀取ObjectInputStream的讀取對象是阻塞的,所以我列表中的所有對象都必須處於正確的狀態。或者我忽略了一些東西?
  • 是否有任何技術/工具/做法捕捉這樣的事情?

謝謝。

+0

幾個問題:不正確的反序列化對象是否一致?如果是這樣,它的狀態與其他狀態有何不同?此外,無論何時反序列化對象,最好假設它們來自惡意來源,並相應地檢查其狀態,例如空值或任何可能危及應用程序的內容。 – 2010-07-21 14:39:30

+0

在串行化被應用程序中的其他對象引用之前,這個對象在每種情況下都不相同 - 在串行化調用它的writeObject()方法之前,它是完全健康的對象。 我還有一個更重要的發現:事實上,當我不遍歷'Container.readObject()'(或'initContainer()'中的'items'時,一切正常!它看起來像我無法正確觸摸readObject()中的反序列化數據,它必須在序列化完成後推遲。也許它是依賴於序列化開始之前對象的現有引用...非常非常奇怪... – mschayna 2010-07-21 15:48:58

回答

0

正如我在評論中寫道的,這個問題是在Container.readObject()期間在序列化收集中觸及項目。這些對象中的一些在此時有空字段。當我推遲在Container以外的反序列化觸發時,這些對象具有正確的字段值。

我的假設

讓有對象與其他物體兒童的野外採集。父母和孩子都可以序列化,也可以收集。在readObject()方法的定製父反序列化過程中,子程序不是完全可訪問的,它們存在但它的反序列化不完整。只有在處理父節點反序列化後,才必須訪問子節點。

這個假設適用於我,但我仍然不知道爲什麼。