快速业务通道

Java:所有的equals方法实现都是错误的? - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-21
 (Point) other;   result = (this.getX() == that.getX() && this.getY() == that.getY()   && this.getClass().equals(that.getClass()));   }   return result;   }   @Override public int hashCode() {   return (41 * (41 + getX()) + getY());   } }

Java:所有的equals方法实现都是错误的?(7)

时间:2011-01-05 司马牵牛译

然后,你就可以将类 ColoredPoint 的实现恢复为之前违反了对称性要求的版本:

public class ColoredPoint extends Point { // 不再违反平衡性要求   private final Color color;   public ColoredPoint(int x, int y, Color color) {   super(x, y);   this.color = color;   }   @Override public boolean equals(Object other) {   boolean result = false;   if (other instanceof ColoredPoint) {   ColoredPoint that = (ColoredPoint) other;   result = (this.color.equals(that.color) && super.equals(that));   }   return result;   } }

在这里,类 Point 的实例被认为与系统类的其他实例是相等的,仅当对象具有相同的坐标,并且具有相同的运行时类,即每个对象 .getClass() 返回相同的值。 新的定义可以满足对象性和传递性的要求,因为现在对不同类之间的每次对比都将返回 false。因此,颜色点永远不会与普通点相等。这种约定看起来是合理的,当有人会指出新的定义太过严格了。

下面使用稍微有点绕的方式定义位于坐标(1, 2)上的点:

Point pAnon = new Point(1, 1) {   @Override public int getY() {   return 2;   } };

pAnon 等于 p 吗?答案是否定的,因为与 p 和 pAnon 关联的 java.lang.Class 对象是不同的。对于 p 是 Point 类,而对于 pAnon,它是 Point 的一个匿名子类。 但显然,pAnon 只是位于坐标(1, 2)上的另一个点。 认为它与 p 不同,看起来并不合理。

明智的方式:canEqual 方法

从以上各种情况,看起来我们进退两难。是否存在一种明智的方式,在类层次结构的多个分层中对等值比较进行重定义,而同时满足其约定?事实上,有这样一种方式,但它需要另一个方法来重定义equals和 hashCode。这个想法是,只要类重定义 equals(和 hashCode),它就应该同时显式地声明,该类的所有对象与使用不同等值方法的超类中的对象,绝对不会相等。通过对重定义equals的每个类添加方法 canEqual 就可以实现。以下为该方法的原型:

public boolean canEqual(Object other)

当其他(other)对象是(重)定义了 canEqual 的类的实例时,该方法应返回 true,或者返回 false。它从equals中调用,以确保这些对象使用2种方式都是可比较的。下面是类 Point 新的也是最后的一个实现:

public class Point {   private final int x;   private final int y;   public Point(int x, int y) {   this.x = x;   this.y = y;   }   public int getX() {   return x;   }   public int getY() {   return y;   }   @Override public boolean equals(Object other) {   boolean result = false;   if (other instanceof Point) {   Point that = (Point) other;   result = (that.canEqual(this) && this.getX() == that.getX() && this.getY() == that.getY());   }   return result;   }   @Override public int hashCode() {   return (41 * (41 + getX()) + getY());   }   public boolean canEqual(Object other) 

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号