Item 8 ~ 12讲了Methods Common to All Objects,Object类里面的一些不是final的方法。
这篇讲的是override equals方法的时候要遵守的约定。
首先,如果不需要覆写那是最好的,如果满足了下面的条件就不需要覆写:
不需要override的情况:
- Each instance of the class is inherently unique
比如Thread代表活动实体,而不是值(不懂)。 - 不关心类是否提供「逻辑相等」的测试功能。
- superclass已经覆写了equals。
- 类是私有的,可以确定equals不会被调用。
需要覆写的情况
如果类有自己的「逻辑相等」概念的话。比如String
,不但要比对instance,还要比对每个char是否一致,instance一致自然是相等的(自反性reflexive),instance不相等,每个char相等,也返回true。
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = count;
if (n == anotherString.count) {
int i = 0;
while (n-- != 0) {
if (charAt(i) != anotherString.charAt(i))
return false;
i++;
}
return true;
}
}
return false;
}
覆写的时候需要遵守的general contract
- reflexive
x.equals(x) must be true - symmetric
x.equals(y) must be the same as y.equals(x) - transitive
x-->y-->z - consistent
多次调用结果一致。 - 非null类型的引用,x.equals(null)必须返回false
注意
这些contract看似很容易符合,但是文中对每个情形都举了反例,告诉读者这些条件是很容易不知不觉见违反的。具体可看文末链接。
当完成编写之后,要编写单元测试来验证上面的这些特性。
See also:
http://blog.csdn.net/partner4java/article/details/7066349