JAVA拾遗 - 如何正确地覆盖equals方法
2016-09-19 11:30
232 查看
本文思想来自于Effective Java第二版 3.1章节,实为阅读总结,如果读者有疑惑的地方强烈建议阅读这个章节。
何时覆盖Equals方法
何时不应该覆盖
覆盖equals方法看上去是一件简单的事情,但是很多覆盖的方法都会导致一些隐性的BUG,最容易避免这些问题的方法就是 不覆盖 equals方法,在这种情况下每个类都只与其自身相等,如果满足以下任何一个条件,就不应该覆盖equals方法类的每个实例在本质上都是唯一的
对于代表活动实体而不是值的类来说,如Thread等类。Object类提供的equals方法能够实现这些类的正确行为
不关心类是否提供了“逻辑相等”的测试功能
如
java.util.Random覆盖了equals,以检查两个Random示例是否产生相同的随机实例,但是设计者并不认为客户需要这些功能,在这种情况下单纯Object的equals方法就足够了
超类已经覆盖了equals方法,而从超类继承过来的equals方法对于子类也是合适的
大多数的Set都实现从AbstructSet继承equals实现,大多数List实现从AbstructList继承equals实现,大多数Map实现从AbstructMap继承equals实现
类是私有的或者是包级私有的,可以确定其equals方法永远都不会调用
在这种情况下应该覆盖其equals方法,以防止其被意外调用。如:
@Override public boolean equals(Object o) { throw new AssertionError();//method is never called }
何时应该覆盖Equals呢?
如果类具有自己特有的“逻辑相等”概念(不同于对象等同的概念),且超类并没有覆盖equals方法以实现期望的行为,我们就应覆盖equals方法。比如说“值类”的情况。我们在对比值类的时候,单纯想知道其在逻辑上是否相等,而不想了解他们是否指向同一个对象。同时这样也使得这个类的实例可以被用作map的key,或者集合的元素,使得映射或者集合能够表现出预期的行为。
equals方法的特性
equals方法实现了等价关系(equivalence relation):自反性(reflexive)—>
x != null && x.equals(x) == true
对称性(symmetric)—>
if(x != null && x.equals(y))可以推出
y.equals(x)
传递性(transitive)—>
x != null && x.equals(y) == true && y.equals(z)可以推出
x.equals(z)
一致性(consistent)—>对于非null的x、y,只要equals的比较操作在对象中所用的信息没有被修改,多次调用equals返回的一致是true或者一致是false
对于非null的x,
x.equals(null)返回值一定是false
John Donne说过,没有哪个类是孤立的。你需要不断地把一个类的实例传递给另外一个类的实例,在传递过程中,很多类的都依赖于是否遵守equals约定!
覆盖的注意事项
1.覆盖时总是要覆盖hashCode方法2.别想着把equals做得太“智能”
3.千万别把equals方法中的Object参数对象替换成其他类型(从Override变成Overload!)
4.在每次覆盖equals方法都逐一审查equals 的五个约定,就能避免很多隐藏的BUG!
相关文章推荐
- JAVA正确地自定义比较对象---如何重写equals方法和hashCode方法
- 如何在Java中避免equals方法的隐藏陷阱
- Effective Java Item8-在覆盖equals(Object类的nonfinal方法)时遵循接口规范
- Effective java3——覆盖equals方法的通用约定
- 如何重写Java中的equals方法
- 关于==和equals()方法&Java中string与char如何转换&String,StringBuffer
- 如何在Java中避免equals方法的隐藏陷阱
- java equals方法的覆盖
- 如何覆盖Object类中的equals(),hashCode(),toString()方法
- Java探索之旅(12)——equals方法及其覆盖
- 如何在Java中避免equals方法的隐藏陷阱
- 覆盖 equals 方法时应同时覆盖 hashCode 。(java)
- 【转】如何在Java中避免equals方法的隐藏陷阱
- Java探索之旅(12)——equals方法及其覆盖
- 如何在Java中避免equals方法的隐藏陷阱
- 如何在Java中避免equals方法的隐藏陷阱
- 如何在Java中避免equals方法的隐藏陷阱
- 如何在Java中避免equals方法的隐藏陷阱
- 如何在Java中避免equals方法的隐藏陷阱
- java覆盖equals()方法时总要覆盖hashCode()