您的位置:首页 > Web前端

effective java笔记------重载equals方法

2013-02-16 21:02 309 查看
什么时候重载equals方法?

我们先来看一看equals()方法在Object类中的实现:

public boolean equals(Object obj) {
return (this == obj);
}
在Object类中,equals()方法用于判断两个引用是否指向同一个对象,因此,如果你的目的正是如此,就大可不必费力重载这个方法了.这种方法的实现使用与代表活动实体而不是"值"的类,比如Thread.

因此,需要重载equals()的类就被限制在值类范畴,因为这时候用户不是想判断两个引用是否指向同一个对象,而是想判断这两个引用的值是否"逻辑相等".
但是下面两种情况,即使该类是值类,equals()方法也不需要被重载:
1.实例受控类-------每个值最多只存在一个对象.
2.枚举类
对于上述两种类,判断值相等和判断实例相等实际上是一回事.

重载equals()方法要遵循的四个原则

当我们真正需要重载一个equals()方法时应该如何做呢?java规范里之处equals()重载时要遵守五个原则:
1.自反性(reflexive):即x.equals(x)总是返回true,其实这条很难违反.
2.对称性(symmetic):如果x.equals(y)返回true,那么y.equals(x)也应该返回true,反之亦然.
3.传递性(transitive):如果x.equals(y)返回true,y.equals(z)也返回true,那么x.equals(z)也应该返回true
4.一致性(consistent):如果x.equals(y)返回true,在x和y中的信息不发生改变的情况下,多次调用x.equals(y)都应该返回true.
5.非空性:即x.equals(NULL)永远返回false,没有对象和NULL相等

如何实现高质量的equals()方法?

1.“==”检测和instanceof检测:一个重载的equals()方法通常会在开始时进行一下两项检测

@override
public boolean equals(object o) { //参数类型必须是object,否则就不是重载而是新方法了
if(o == this){                //当比较操作比较昂贵时,值得这么做
return true;
}
if(!o instanceof ClassA){     //确保下面的强制类型转换可以正常进行
return false;
}
ClassA a = (ClassA) o;
//......
}


2.比较类中的“关键”域,避免冗余域的比较

例如两个矩形的长宽相等,那么它的面积自然相等,这是就不要在equals方法中增加比较面积的步骤

3.由于Float.NaN,-0.0f等常量的存在,double和float两种基本类型的比较要使用他们各自的compare()方法,其他基本类型的域可以直接使用“==”比较

4.某些对象引用域包含NULL可能是合法的,此时应采用如下实现

(field == null ? o.field == null : field.equals(o.field));
5.如果数组是关键域,并且每个元素都很重要,那么要使用Arrays.equals方法

6.测试,一定要测试!

编写完成后,一定要测试方法是否满足上面五个原则!!!

其他注意事项

1.重载equals方法后一定要覆盖hashCode方法(后面会讲)

2.不要让equals方法过于智能,过犹不及,我们无法在扩展可实例化类的同时,既增加新的值组件,同时又能满足equals约定,是不可能的。除非愿意放弃面向对象的抽象所带来的优势
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: