当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
为false
值返回null
,为什么不将初始测试简化为:
if (!(obj instanceof MyClass))
return false;
我也不清楚为什么这段代码会在字段比较中明确使用this.field
(可能是为了避免混淆)但是出于同样的原因不会使用this.getClass()
?
NetBean的形式是否有任何优势?
答案 0 :(得分:4)
instanceof
与班级比较之间存在大差异。请注意(例如)HashMap
实例为instanceof
AbstractMap
,但AbstractMap
的{{1}}不应将equals
other
视为AbstractMap
1}}如果它实际上是HashMap
。 instanceof
测试允许或其任何子类型的实例,因此不是对称的。 equals
需要对称性。 (以下示例。)
Netbeans代码似乎相当笨拙并且可以更简洁地编写,但是按照给定的顺序操作是有意义的默认起点。 (虽然我已经包含this
检查。)这是一对罕见的类,可以有equal
个实例,因此使用getClass
进行默认实现是合理的。< / p>
只是提醒我们所有the contract:
null
引用值x
,x.equals(x)
应返回true
。null
引用值x
和y
,x.equals(y)
应返回true
并且仅当y.equals(x)
返回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
true {{ 1}}修改了or consistently return
等于对象的比较。, provided no information used in
参考值null
,x
应返回x.equals(null)
。在我90年代早期的Java时代,我违背了这份合同(不知不觉中),based on the answers to this question,我不是唯一一个。我使用false
(和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;
}
}
这违反了合同。