日期:2014-05-20  浏览次数:20773 次

我们爱分享---Obey the general contract when overriding equals
这两天热度有点低,也没什么好写的,就随便奉献上Effective Java中的一条规则
Obey the general contract when overriding equals

今天只讲其中的一个原则及其注意事项:
symmetric: For any reference values x and y, x.equals(y) must return true if and only if y.equals(x) returns true.
可以称之为对称性或者交换性原则,即x.equals(y)返回true是y.equals(x)的充要条件。

理论大家会讲,但是在override的时候,大家很容易出错。

Java code

public class A {
  public int x;
  public boolean equals(Object obj) {
    if (! (obj instanceof A)) {
      return false;
    }
    A that = (A) obj;
    return this.x == that.x;
  }
}



这段代码粗看上去没有任何问题(null instanceof A也是false),但实际上,这段代码在将来的某个时刻很有可能导致symmetric原则被破坏。
Java code

public class B extends A {
  public int y;
  public boolean equals(Object obj) {
    if (! (obj instanceof B)) {
      return false;
    }
    B that = (B) obj;
    return super.equals(obj) && this.y == that.y;
  }
}


此时,无论B中间的equals方法如何调整,都会导致symmetric原则被破坏:
Java code

A a = new A();
B b = new B();

System.out.println(a.equals(b)); // true,B是A的子类,b当然是instanceof A,而且由于之比较a.x和b.x,所以true
System.out.println(b.equals(a)); // false,a不是B的实例



老实说,这个世界上没有一个完美的修正方案,这点不光是Java,C#等OO语言都有这个问题。

1 如果所有的类都可以修改的话,那么你可以在每一个类中都override equals方法,并用this.getClass() == obj.getClass()来判断(只适用于所有类都是自己写的,最顶层的父类直接继承自Object,而且,每一层都添加了字段)
2 如果能够用组合的话,尽量使用组合,而不是继承“Favor composition over inheritance”,通过这种方式绕过去
3 忍受它,因为这个问题,其实你天天可能在JDK中间碰到这个问题,比如java.util.Date及其java.sql包中间的子类,所以当你如果可能碰到java.util.Date实例和java.sql.Timestamp实例做equals的时候,你就该当心了。

------解决方案--------------------
java.util.Date的equals用的是instanceof判断并不代表我们就一定也非得用instanceof。
------解决方案--------------------

------解决方案--------------------
老师说 好像可以用反射的机制解决这个问题
------解决方案--------------------
不错。是容易犯这个错。
------解决方案--------------------
支持分享,话说effective java的规则真的很不错
------解决方案--------------------
学习学习

lz厉害
------解决方案--------------------

------解决方案--------------------
大胡子干嘛去了
------解决方案--------------------
好贴 好贴!学习了!
------解决方案--------------------
探讨
这两天热度有点低,也没什么好写的,就随便奉献上Effective Java中的一条规则
Obey the general contract when overriding equals

今天只讲其中的一个原则及其注意事项:
symmetric: For any reference values x and y, x.equals(y) must return true if and on……

------解决方案--------------------
http://topic.csdn.net/u/20110813/15/f6b615be-e2b6-4600-aa5d-a9723f309c4f.html
------解决方案--------------------
乐高坦克的贴贴一定要顶~!~!
------解决方案--------------------
来学习的,谢谢分享
------解决方案--------------------
哇,学习中