如果一个被序列化的对象中,包含有HashMapHashSetHashTable集合,则这些集合中不允许保存当前被序列化对象的直接或间接引用。因为,这些集合类型在反序列化的时候,会调用到当前序列化对象的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中的位置放置错误,对象被破坏。