我重写了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
,equals()
内的标准Foo
方法如下所示:
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);
}
equals()
内的标准Bar
方法如下:
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
。如果我通过bar.equals(foo)
合同的对称条款调用equals()
,则会因为equals()
Bar
内(!(other instanceof Bar))
true
Bar
而被打破,使equal()
的{{1}}方法返回false
,这是不正确的,它应该是true
,逻辑(两个对象String baz
等于彼此),以及对称性条款,如果x.equals(y)
,y.equals(x)
本身就是true
。
我知道覆盖getClass()
的{{1}} vs instanceof
参数,并且不想要其中一个参数。
这让我想到了我的实际问题。在这种情况下,如何正确地覆盖遵循标准Java协定的equals()
方法以实现相等?
答案 0 :(得分:1)
根据你的问题
Foo
具有相同的Bar
baz
可以等于Foo
如果Foo
具有相同的baz
Bar
可以等于Bar
如果baz
具有相同的Foo
Bar
可以等于equals()
这清楚地表明Bar
和Foo
将{em>与Bar
完全相同的实现。因此,您根本不应该覆盖它。
如果你试图忽略这一点并覆盖它,你会得出一个明显的结论:你不能将.equals()
转发给Bar
,但你可以将两个参数都转换为{{1}}。一旦你这样做,你就会意识到你可以简单地使用{{1}}中的{{1}}。