当NetBeans自动生成equals
方法时,它以以下形式:
@Override
public boolean equals(Object obj) {
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final MyClass other = (MyClass)obj;
if (!Object.equals(this.field, other.field))
return false;
return true;
}
这看起来很啰嗦。Java的instanceof
为null
值返回false
,所以为什么不将初始测试简化为:
if (!(obj instanceof MyClass))
return false;
我也不清楚为什么这段代码会显式地在字段比较中使用this.field
(大概是为了避免混淆),但出于同样的原因不会使用this.getClass()
?
NetBean的形式有什么优势吗?
instanceof
和类比较有大的差异。请记住(例如)HashMap
实例是instanceof
AbstractMap
,但如果AbstractMap
的equals
实际上是HashMap
,则不应考虑other
和AbstractMap
。instanceof
测试允许类型或其任何子类型的实例,因此不是对称的。equals
要求对称。(下面的例子。)
Netbeans代码确实看起来相当呆板,可以写得更简洁,但是按照给定的顺序,这些操作作为默认起点是有意义的。(不过我会附上this
支票。)这对类很少有equal
实例,所以使用getClass
作为默认实现是合理的。
只是提醒我们所有的合同:
-
是自反性:对于任何非
null
的参考值x
,x.equals(x)
应该返回true
。 -
对称:对于任何非
null
的参考值x
和y
,当且仅当y.equals(x)
返回true
时,x.equals(y)
应该返回true
。 -
可传递:对于任何非
null
的参考值x
、y
和z
,如果x.equals(y)
返回true
,y.equals(z)
返回true
,那么x.equals(z)
应该返回true
。 -
一致:对于任何非
null
参考值x and
y, multiple invocations of
x.equals(y)consistently return
trueor consistently return
false, provided no information used in
equals对对象的比较被修改 - 对于任何非
null
的参考值x
,x.equals(null)
应该返回false
。
在90年代早期的Java时代,我打破了这个契约(无意中),根据对这个问题的回答,我不是唯一的一个。我使用instanceof
(和super.equals
),如下所示:
class Parent {
private int foo;
protected int getFoo() {
return foo;
}
Parent(int f) {
this.foo = f;
}
// ...
@Override
public boolean equals(Object obj) {
// WRONG, see below
if (obj == this) {
return true;
}
if (!(obj instanceof Parent)) {
return false;
}
return this.foo == ((Parent)obj).foo;
}
}
class Child extends Parent {
private int bar;
Child(int f, int b) {
super(f);
this.bar = b;
}
// ...
@Override
public boolean equals(Object obj) {
// WRONG, see below
if (obj == this) {
return true;
}
if (!(obj instanceof Child)) {
return false;
}
return super.equals(obj) && this.bar == ((Child)obj).bar;
}
}
这里的问题是它不是对称的:
Parent p = new Parent(1);
Child c = new Child(1, 2);
System.out.println(p.equals(c)); // true
System.out.println(c.equals(p)); // false
这违反了合同。