小弟最近用HashSet时无意看了下它的源码,发现一段奇怪的代码,不知是小弟所学不精还是java源码编写者别有深意呢

[code="java"]
map = (((HashSet)this) instanceof LinkedHashSet ?
new LinkedHashMap(capacity, loadFactor) :
new HashMap(capacity, loadFactor));
[/code]

这是HashSet中readObject的一段代码
LinkedHashSet是HashSet的子类,这里却在instanceof前对this用了强制转换
虽说LinkedHashSet用的也是这段代码,但这里的强制转换怎么看都觉得有点别扭似的

按小弟的理解,readObject应该是new了之后就使用,那this的类型也就该是new的类型吧?
又或者说是为了容错?为了编码的方便理解?

小弟学java还是新手,希望各位高手们不吝指教一下,谢谢

首先,看起来你还不清楚writeObject()和readObject()方法是用来实现对象的序列化和反序列化的

这个this是指反序列化之后的引用

反序列化是不会调用类的构造方法的

readObject方法是用来从流中重建HashSet对象。

这里的this,不是指当前对象,而是指从流中获取的对象,所以需要首先强制装换成HashSet。

可以先学习一下序列化和反序列化。

[b]首先: LinkedHashSet extends HashSet

其次: LinkedHashSet 只是覆盖了 HashSet中的几个方法(见源码)。

注意的是 LinkedHashSet并没有覆盖 readObject 、 writeObject这2个在反序列化、序列化中要用的方法。所以当序列化、反序列化 LinkedHashSet的时候,会调用 父类 HashSet中的readObject 、 writeObject方法。

为了方便2个不同类的使用,所以,进行一下判断,为父类、子类生成不同的map对象。

[color=blue]简单地说:由于LinkHashSet继承了readObject的方法,所以为了区分父类、子类,所以作出了判断。[/color][/b]

[code="java"]
map = (((HashSet)this) instanceof LinkedHashSet ?
new LinkedHashMap(capacity, loadFactor) :
new HashMap(capacity, loadFactor));[/code]
[color=blue][b]
如果不这样设计,可能是以下的结果:[/b][/color]
[b]
HashSet中:[/b]

[code="java"]map = new HashMap(capacity, loadFactor));[/code]
[b]
LinkedHashSet中:[/b]

[code="java"]map = new LinkedHashMap(capacity, loadFactor));[/code]