覆盖 equals 时请遵守通用约定——《effective Java》第三版

        覆盖 equals 方法看起来似乎很简单,但是有许多覆盖方式会导致错误,并且后果非常严重。最容易避免这类问题的办法就是不覆盖 equals 方法,在这种情况下,类的每个实例都只与它自身相等。如果满足了以下任何一个条件,这就正是所期望的结果:

       类的每个实例本质上都是唯一的。对于代表活动实体而不是值(value)的类来说确实如此,例如 Thread。Object 提供的 equals 实现对于这些类来说正是正确的行为。

        类没有必要提供“逻辑相等”(logical equality)的测试功能。例如,java.util.regex.Pattern 可以覆盖 equals,以检查两个 Pattern 实例是否代表同一个正则表达式,但是设计者并不认为客户需要或者期望这样的功能。在这类情况之下, Object 继承得到的 equals 实现已经足够了。

        超类已经覆盖了equals,超类的行为对于这个类也是合适的。例如,大多数的Set 实现都从AbstractSet 继承 equals 实现,List 实现从Abstractlist 继承 equals 实现,Map 实现从AbstractMap 继承 equals 实现。

        类是私有的,或者是包级私有的,可以确定它的 equals 方法永远不会被调用。如果你非常想要规避风险,可以覆盖 equals 方法,以确保它不会被意外调用:Override public boolean equals(Object o) {

throw new AssertionError();

// Method is nevercalled

}

           equals 方法实现了等价关系(equivalence relation),其属性如下:

□自反性(reflexive):对于任何非 null 的引用值x,x.equals(x)必须返回true。

口对称性(symmetric):对于任何非 null 的引用值×和 y,当且仅当y.equals(x)返回true时,x.equals(y)必须返回true。

□传递性(transitive):对于任何非 null 的引用值 x、y和 z,如果 x.equals(y)返回true,并且y.equals(z)也返回true,那么x.equals(z)也必须返回true。

口一致性(consistent):对于任何非 null 的引用值 ×和 y,只要 equals 的比较操作在对象中所用的信息没有被修改,多次调用x.equals(y)就会一致地返回true,或者一致地返回 false。

口对于任何非 null 的引用值 x,x.equals(null)必须返回 false。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值