8.覆盖equals时请遵守通用约定

一、不覆盖equals

==是物理相等  

equals是逻辑相等

Object类的equals方法的实现:物理相等的话就逻辑相等。

不覆盖equals的情况下,类的每个实例都与它自身相等:

1、类的每个实例本质上都是唯一的

对于代表活动实体而不是值(value)的类来说确实如此,比如Thread

2、不关心类是否提供了"逻辑相等"的测试功能

3、超类已经覆盖了equals,从超类继承过来的行为对于子类也是合适的

例:Set实现类都继承了AbstractSet类的equals方法,List实现类都继承了AbstractList类的equals方法

4、类是私有的或是包级私有的,可以确定它的equals方法永远不会被调用 ?

这种情况下,只是对equals的一种废弃,并没有新加什么功能

二、覆盖equals:

类需逻辑相等时,而父类没覆盖equals实现期望行为:

比如要判断两个student是否是同一个人,这个时候我们就需要按需重写equals

覆盖equals的时候就必须要遵守它的通用约定:

自反性(reflexive)   x.equals(x)  true

对称性(symmetric)  y.equals(x)  true时,x.equals(y)  true

传递性(transitive)   x.equals(y)为true,y.equals(z) true, x.equals(z)true

一致性(consistent)  只要没修改,多次调用x.equals(y)就会一致地返回true,或者false

x.equals(null)必须返回false

有些类(如集合,HashMap)与equals方法息息相关,重写时小心

三、高质量的equals

1、使用==操作符检查“参数是否为这个对象的引用”。 性能优化

2、使用instanceof操作符检查“参数是否为正确的类型”。 

3、把参数转换成正确的类型。 

4、对于该类的每个“关键(significant)”域,检查参数中的域是否与该对象中对应的域相匹配。 

else if (!name.equals(other.name)) 改成: 

else if (name != other.name && !name.equals(other.name)

5、写完equals方法之后,问自己:是否的对称的、传递的、一致的。 

四、告诫

1、覆盖equals时总要覆盖hashcode;

2、不要企图让equals方法过于智能;

只是想测试值是否相等

3、不要将equals声明中的Object对象替换为其他的类型

这样就变成了equals方法的重载,而不是重写。  可以添加@Override注解 来避免这种错误。

https://www.cnblogs.com/wangliyue/p/4448085.html

https://blog.csdn.net/w_linux/article/details/80041386

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 做一棵树,好吗 在前世的喧嚣里生根 不去想烟火和浮尘 北风留不下痛苦 只有叶落归根 也不用去想岁月 不过添了几道年...
    九月的马尾阅读 252评论 0 3
  • 这里有两块大的草坪,在这个钢筋水泥遍布的城市里,这样可以放肆奔跑的地方成了孩子们的乐园,而校园这样的环境又给草坪添...
    泥水佬阅读 253评论 0 0
  • 看了这则新闻,仔细阅读了一下当事人的经历,不免心生寒意。我们要谴责还是叹惋,毕竟这不应该是为人所艳羡的行为。 “高...
    e1215d1d3131阅读 280评论 0 4