Item 8: Obey the general contract when overriding equals

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

你可能感兴趣的:(Item 8: Obey the general contract when overriding equals)