重写正确的Java等于方法
我重写了Java类中的equals()方法,发现了一个我无法解释的难题。
标准equals()合同规定了这一点:
因此,标准的equals()方法可以这样构造:
public boolean equals(Object other) {
if (null == other) return false;
if (this == other) return true;
if (!(other instanceof MyClassName)) return false;
MyClassName that = (MyClassName) other;
return this.myMemberVariable.equals(that.name);
}
给定类Foo和类Bar extends Foo ,都使用成员变量String baz , Foo内的标准equals()方法看起来像:
public boolean equals(Object other) {
if (null == other) return false;
if (this == other) return true;
if (!(other instanceof Foo)) return false;
Foo that = (Foo) other;
return this.baz.equals(that.name);
}
Bar内的标准equals()方法看起来像这样:
public boolean equals(Object other) {
if (null == other) return false;
if (this == other) return true;
if (!(other instanceof Bar)) return false;
Barthat = (Bar) other;
return this.baz.equals(that.name);
}
如果我有对象Foo foo = new Foo("Test"); 和Bar bar = new Bar("Test"); ,并且我调用了foo.equals(bar) ,这将返回true 。 如果我通过equals()合约的对称子句调用bar.equals(foo) ,这是因为在Bar equals()中, (!(other instanceof Bar))是true ,所以Bar的equal()方法返回false ,这是不正确的,它应该是true ,通过逻辑(两个对象String baz是彼此相等的),并通过对称子句,其中如果x.equals(y) , y.equals(x)本质上是true 。
我知道用于重写equals()的getClass() vs instanceof参数,并且不需要这些参数中的另一个参数。
这让我想起了我的实际问题。 在这种情况下,如何正确地重写遵循标准Java合约的equals()方法以实现相等性?
根据你的问题
baz Foo可以等于Bar baz Foo可以等于Foo baz Bar可以等于Bar 这清楚地表明Foo和Bar将具有与equals()完全相同的实现。 因此,你不应该重写它。
如果您试图无视这一点并覆盖它,那么您会得出一个明显的结论:您无法将Bar下降到Foo ,但您可以将这两个参数都投射到Bar 。 只要你做到这一点,你会发现你可以简单使用.equals()从Bar 。
上一篇: Overriding Proper Java equals method
下一篇: compareTo triggered at first add call on TreeSet in Java 1.7
