您的位置:首页 > 其它

第8条 对于所有对象都通用的方法——覆盖equals时请遵守通用约定

2016-05-03 15:52 411 查看
        ==表示的是物理上的相等,equals()表示的是逻辑上的相等。因为每一个类的实例对象本质上都是唯一的,利用物理相等(==)是指一个实例只能等于它自身。利用逻辑相等(equals())是指一个实例是否与另一个实例的某些关键域相等,从而来判断这两个实例是否相等。Object类的equals()方法的实现:物理相等的话就逻辑相等。

1、不需要覆盖Object类的equals方法情况

        1)希望这个类的实例只能和自身相等,不覆盖equals方法,只继承Object类的equals方法。我们比较这个类的实例对象是否相等,无论是使用 == 或者equals实际上都是进行物理相等的判断。

        2)超类已经覆盖了equals,从超类继承过来的行为对于子类也合适。例如:Set实现类都继承了AbstractSet类的equals方法,List实现类都继承了AbstractList类的equals方法,Map实现类都继承了AbstractMap类的equals方法。

        3)类是私有的或是包级私有的,可以确定它的equals方法永远不会被调用。在这种情况下,最好是对equals方法进行覆盖,以防止它被意外调用:

@override public boolean equals(object o){
Thrownew AssertionError();//Method is never called
}

2、需要覆盖Object类的equals方法情况

        如果类具有自己特有的“逻辑相等”概念,而且超类还没有覆盖equals以实现期望的行为,这时我们就需要覆盖equals方法。这通常属于“值类”的情形。

也存在例外情况,有一种“值类”不需要覆盖equals方法,即用实例受控确保“每个值至多只存在一个对象”的类。枚举类型就属于这种类。对于这样的类而言,逻辑相同与对象等同是同一回事,因此Object的equals方法等同于逻辑意义上的equals方法。

3、equals 方法在非空对象引用上实现相等关系

        1)自反性: x.equals(x) 必须返回true  。实例自身必然逻辑相等。

        2)对称性: x.equals(y) 与 y.equals(x) 返回结果应该相同,同为true或者同为false。

        3)传递性: x.equals(y)返回true,y.equals(z)返回true,则x.equals(z)应该返回true。

        4)一致性: 只要比较的实例对象的关键属性值没有改变 ,那么无论调用多少次equals方法返回的结果都应该相同,一致。

        5)对于非null的x实例,x.equals(null) 永远返回false。

4、实现高质量equals方法的诀窍

        1)使用==操作符检查“参数是否为这个对象的引用”;

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

        3)把参数转换成正确的类型;

        4)对于该类中的每个“关键”域,检查参数中的域是否与该对象中对应的域相匹配(为了获得最佳性能,应该先比较最有可能不一致的域,或者开销最低的域,最理想的情况是两个条件同时满足的域);

        5)当编写完equals方法后,应该问自己三个问题:它是否是对称的、传递的和一致的?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: