2010-07-21 298 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()方法的定制父反序列化过程中,子程序不是完全可访问的,它们存在但它的反序列化不完整。只有在处理父节点反序列化后,才必须访问子节点。

这个假设适用于我,但我仍然不知道为什么。