如果一個被序列化的對象中,包含有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中的位置放置錯誤,對象被破壞。