java puzzler 91
总之序列化是很脆弱的,请谨慎使用。
如果一个HashSet、HashTable、HashMap被序列化,那么请确认它们的内容没有直接或间接地引用它们自身。
运行程序,抛出异常:
分析:
(1)反序列化Sub实例中的Super的域,唯一的域是set,它包含一个HashSet的引用。
(2)HashSet包含HashMap的引用,HashMap的键是该散列集合的元素。
(3)HashSet 类有一个readObject 方法,它创建一个空的HashMap,并且使用HashMap 的put 方法,针对集合中的每个元
素在HashMap 中插入一个键-值对。
(4)put 方法会调用键的hashCode 方法以确定它所在的单元格(bucket)。在我们的程序中,散列映射表中唯一的键就是Sub
的实例,而它的set 域正在被反序列化。这个实例的子类域(subclass field),即id,尚未被初始化,所以它的值为0,即所有int 域的缺省初始值。
(5)Sub 的hashCode 方法将返回这个值,而不是最后保存在这个域中的值666。因为hashCode 返回了错误的值,相应的键-值对条目将会放入错误的单元格中。当id域被初始化为666 时,一切都太迟了。当Sub 实例在HashMap 中的时候,改变这个域的值就会破坏这个域,进而破坏HashSet,破坏Sub 实例。