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

你可能感兴趣的:(8.覆盖equals时请遵守通用约定)