本文结合《Effective Java》第三章条目8《覆盖equals时请遵守通用约定》和自己的理解及实践,讲解了在覆盖equals时需要遵守的规范,文章发布于专栏Effective Java,欢迎读者订阅。
Java中用equals方法来判断两个对象是不是相等,equals方法是Object类就拥有的方法,因而属于所有对象通用的方法,使用方式很简单:a.equals(b) ,返回true或false。下面进入正题。
什么时候才应该覆盖equals方法
我们都知道,如果不覆盖equals方法,那么就是使用的父类的equals方法,我们可以来看看Object的equals方法都做了什么:
public boolean equals(Object obj) {
return (this == obj);
}
显然,Object只是使用==运算符,简单地判断两个对象是不是同一个对象,也就是说,new出来的两个对象,不管他们属性是不是相同,都是不相等的。而实际使用中,我们常常会碰到“逻辑相等”的需求,比如,我们认为两个半径相同的圆,他们是相等的,这个时候,如果圆的父类,还没有覆盖equals方法实现这个逻辑相等,那么,就需要在类里面去覆盖equals方法。
总结一下:如果类具有自己特有的“逻辑相等”概念,而且父类还没有覆盖equals方法实现期望的逻辑,这时候就需要我们覆盖equals方法。
equals方法的五条约定
由于在很多集合的内部方法中,都会使用到equals方法,比如contains方法,因此我们在覆盖equals方法的时候,需要遵循以下规定,否则会造成异常。
对于不等于null的x、y、z,有以下规定:
> 自反性
x.equals(x)==true。
> 对称性