一、不覆盖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