当我读了一本
Java书时,作者曾经说过,在设计一个类时,使用equals()与继承通常是不安全的.例如:
public final class Date { public boolean equals(Object o) { // some code here } }
在上面的类中,我们应该把final,所以其他类不能继承.我的问题是,为什么允许另一个类继承自己是不安全的?
解决方法
因为很难(不可能?)使它正确,尤其是
symmetric property.
说你有班车和班车延长车.如果参数也是车辆并且具有相同的权重,Vehicle.equals()将成立.如果你想实现Car.equals(),它应该只有在参数也是一个车,而不是重量的时候应该产生一个真实值,它也应该比较make,引擎等.
现在想象下面的代码:
Vehicle tank = new Vehicle(); Vehicle bus = new Car(); tank.equals(bus); //can be true bus.equals(tank); //false
如果巧合坦克和公共汽车重量相同,则首次比较可能会产生真实性.但是由于坦克不是一辆车,所以将它与汽车进行比较,总是会产生错误.
你几乎没有工作:
> strict:当且仅当它们具有完全相同的类型(并且所有属性相等)时,两个对象相等.这是坏的,例如当你的子类几乎没有添加一些行为或装饰原始类.一些框架是子类化你的类,没有你注意到(Hibernate,Spring AOP与CGLIB代理…)
> loose:如果两个对象的类型是“兼容的”,并且它们具有相同的内容(语义上),则两个对象相等.例如.如果它们包含相同的元素,两个集合是相等的,那么一个是HashSet并且另一个是TreeSet并不重要(感谢@veer指出这一点).
这可能是误导.采用两个LinkedHashSets(插入订单作为合同的一部分).然而,由于equals()仅考虑了原始Set合同,所以即使对于明显不同的对象,比较也将成为true:
Set<Integer> s1 = new LinkedHashSet<Integer>(Arrays.asList(1,2,3)); Set<Integer> s2 = new LinkedHashSet<Integer>(Arrays.asList(3,1)); System.out.println(s1.equals(s2));
也可以看看