我编写了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
的反序列化已经完成Container
项的反序列化仅被调用(n-1)次(通过计算对其T
方法的调用)readObject()
中有containerInit()
个正确(n)个项目,但其中一个(其中一个不称为反序列化)处于非常奇怪的状态 - 所有字段都有{ {1}}值 - 我的代码在这里抛出NPE 问题:
List<T>
调用而且在所有字段中都为null)?null
读取对象是阻塞的,所以我列表中的所有对象都必须处于正确的状态。或者我忽视了什么?谢谢。
答案 0 :(得分:0)
正如我在评论中所写,问题是在Container.readObject()
期间触摸序列化集合中的项目。其中一些对象在这一刻具有空字段。当我推迟对Container
的反向外部反序列化时,这些对象具有正确的字段值。
我的假设:
让对象父包含其他对象子的字段集合。父母和孩子都可以序列化,也可以收集。在readObject()
方法中的自定义父反序列化期间,不能完全访问子级,它们存在但反序列化不完整。只有在处理父反序列化后才需要访问子项。
这个假设对我有用,但我仍然不知道为什么。