我已经写了我的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