主要有以下几个方面需要注意:
1.重写equals()和hashCode()
当真正需要了解两个引用是否完全相同时,使用==。但是,当需要了解对象本身是否相等时,使用equals()。实际上是要比较两个不同对象的内容在意义上是否等价,除了String类和封装器类(已重写了equals()),需要重写equals().Object内的equals()的方法只使用==运算符进行比较,因此,除非重写equals(),否则只有当两个引用引用相同的对象时,这两个对象才被看做是相等的。另外,如果要使类对象能够用作散列表的键(或者任何数据结构中用于搜索和/或检索对象的元素),则必须重写equals(),使两个不同实例能够被看做是相同的。
我们一般这样重写:
public boolean equals(Object o) {
if(o instanceof Moof) && ((Moof)o).getMoofValue() == this.moofValue)) {
return true;
} else {
return false;
}
}
上面执行了两个操作:
1)确保所测试对象的类型是正确的!用instanceof
2)比较我们关心的属性
注意: equals()、hashCode()和toString()方法都是公有的。下面这种重写是无效的,
class Foo {
boolean equals(Object o) { }
}
一定还要注意参数类型。下面方法是对equals()方法的重载,而不是重写。
class Foo {
public boolean equals(Foo b) { }
}
一定要非常熟悉重写规则,要能够识别类中对Object方法的重写、重载还是非法重新声明。在Foo类中,equals()方法把参数从Object修改为Foo,因此,它是一个重载方法,除非从你自己的代码(它知道这个新的不同方法,而且碰巧被命名为equals)中调用,否则,它不会被调用。
java API中,在equals()方法内定义了一种约定。java约定是一套应该遵守的规则,或者说是想提供其他人所期望的“正确”设计时必须要遵守的内容。有5点:
1.自反性: x.equals(x)应该返回true;
2.对称性:当且仅当y.equals(x)返回true时,x.equals(y)才返回true。
3.可传递性
4.一致性
5.任何非空引用值x,x.equals(null)应该返回false.
如果使用equals()方法,两个对象被认为是相等的,则它们必须具有相同的散列码值。因为Object类的默认散列码总是为每个对象产生一个唯一号,即使重写的equals()方法认为两个或多个对象是相等的,也是这样。所以,为了安全起见,如果重写equals(),一定也要重写
hashCode().