重写java object类的equals方法
- 覆盖equals方法请遵守约定
- 什么情况下要覆盖equals方法
- 容易违反的对称性
- 不易察觉的传递性
覆盖equals请遵守通用约定
似乎覆盖equals方法看起来似乎是一件平常甚至极其简单的事情,
但是有许多覆盖方式会导致错误,并且会表现出超出预期的行为,
而有可能数小时也无法找到错误的位置。(比如说把参数改成了非Object类型)
- 类的每一个实例在本质上都是唯一的
( 从内存的角度来讲是这样的),对于代表活动而不是值(value)的类来说更是如此,
例如Thread。
Object提供equals的实现对于这些类来说是正确的行为
2. 类没有必要提供“逻辑相等”的测试功能
3.超类已经覆盖了equals方法,超类的行为对于子类来说同样也是合适的
4.类是私有的或者是包级私有的,可以确定它的equals方法永远不会被外界调用
如果非常想规避风险,可以覆盖equals方法,
来确保来自Object或者超类的方法永远不会被意外调用。
那么什么时候应该覆盖equals方法
如果类具有自己特有的“逻辑相等”概念(不同于对象等同的概念)
而且超类没有覆盖equals方法。这通常属于"值类"(value class)的情形
例如 一个圆 Circle类,内有一个私有的成员变量radius半径
可以认为,radius相等代表了两个实例在逻辑上相等(或许可以再加上坐标)
再看String类,程序员在利用equals方法比较值对象的引用时,
更希望知道它们逻辑上是否相等,而不希望知道它们到底是不是同一个对象
为满足要求,不仅必须覆盖equals方法,
而且这样做也使得这个类的实例
可以被用作映射表 (map) 的键 (key) ,或者集合set的元素,
使其表现出符合预期的行为
注意:有一种“值类”不需要覆盖equals方法
即实例受控,甚至于单例模式,
确保每个实例的“值”至多只存在一个对象,甚至仅能存在一个实例
(好像太严格了