如果一个被序列化的对象中,包含有HashMap、HashSet或HashTable集合,则这些集合中不允许保存当前被序列化对象的直接或间接引用。因为,这些集合类型在反序列化的时候,会调用到当前序列化对象的hashCode方法,而此时(序列化对象还未完全加载)计算出的hashCode有可能不正确,从而导致对象放置位置错误,破坏反序列化的实例。
示例:
class Super implements Serializable
{
final Set<Super> set = new HashSet<Super>();
}
finalclassSub extends Super
{
privateintid;
public Sub(int id)
{
this.id = id;
set.add(this); //集合中引用了当前对象
}
publicvoid checkInvariant()
{
if(!set.contains(this))
{
thrownew AssertionError("invariant violated");
}
}
publicint hashCode()
{
returnid;
}
publicboolean equals(Object o)
{
return(o instanceof Sub) && (id== ((Sub) o).id);
}
}
这个例子中,将当前对象(Sub对象)放入了对象中的HashSet中,在反序列化set时,因为id属性还未完成初始化,导致hashCode的结果为0,从而导致Sub对象在set中的位置放置错误,对象被破坏。