爲什麼序列化對象中的HashMap、HashSet或HashTable等集合不能包含對象自身的引用

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章