【发布时间】:2011-10-28 09:12:46
【问题描述】:
假设我有一个类,我必须检查多种不同类型的对象。以下列方式覆盖equals() 是否可行/可能?
public boolean equals(Object o){
if(o == null) return false;
if(o instanceof class1){
return this.class1.equals((class1) o);
if(o instanceof class2){
return this.class2.equals((class2) o);
...
}
这会有用吗?我在这里假设我在各自的类中创建了一个静态重载的equals() 方法(尽管只要我强制转换,多态性可能会自动处理这个问题?)。
【问题讨论】:
-
它可能是“有用的”,这取决于你在做什么,但你必须知道在顶部有 equals 和 hashCode Java 的层次结构纯粹是有缺陷的。没有办法解决它。一旦您拥有继承权,您就不能保证等于/哈希码合同。就如此容易。 不可能。 Joshua Bloch 在Effective Java 中很好地、非常清楚且无可争议地解释了这一点。在 Artima 上,Martin Odersky(来自 Scala 的名声)也就此主题发表了精彩的演讲。
-
该代码是合法的,因此是可能的。但是,如果两个对象属于同一类,则说它们相等并不是一个好主意。如果你决心实现这样的实验,那么在 OO 中正确的做法是在每个子类中重写 equals。
-
感谢你们伟大的 cmets。
-
@CedricMartin 不是真的,你可以。您只是不能将属性添加到更改相等性的子类。好吧,甚至前面的句子也是错误的:即使那样,您也可以正确实现等于(即不违反等式关系的任何保证数学属性),但通常不是任何人想要的 - 所以它几乎没有实用价值。实际上 odersky 写了一篇文章来展示如何做到这一点。编辑:或者你只是说你不能保证子类正确实现它?没错,但我想说的很多事情也是如此。
-
@Voo:Odersky 写了一篇文章,显示有一天可以解决这个问题,不使用 equals() 和 hashCode()(他正在创建其他方法)。 Joshua Bloch 说:“根本没有办法扩展一个可实例化的类并添加一个方面,同时保留 equals 契约”。所以我坚持我的断言,如果你想使用继承(是的,这通常意味着拥有类和子类),那么 equals 和 hashCode 在 OO 层次结构的顶部在 Java 中被破坏了。我不认为有解决方法:我只是声明 equals 和 hashCode 不应该存在。
标签: java equals instanceof