effective java笔记------重载equals方法
2013-02-16 21:02
309 查看
什么时候重载equals方法?
我们先来看一看equals()方法在Object类中的实现:
因此,需要重载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()方法通常会在开始时进行一下两项检测
2.比较类中的“关键”域,避免冗余域的比较
例如两个矩形的长宽相等,那么它的面积自然相等,这是就不要在equals方法中增加比较面积的步骤
3.由于Float.NaN,-0.0f等常量的存在,double和float两种基本类型的比较要使用他们各自的compare()方法,其他基本类型的域可以直接使用“==”比较
4.某些对象引用域包含NULL可能是合法的,此时应采用如下实现
6.测试,一定要测试!
编写完成后,一定要测试方法是否满足上面五个原则!!!
其他注意事项
1.重载equals方法后一定要覆盖hashCode方法(后面会讲)
2.不要让equals方法过于智能,过犹不及,我们无法在扩展可实例化类的同时,既增加新的值组件,同时又能满足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约定,是不可能的。除非愿意放弃面向对象的抽象所带来的优势
相关文章推荐
- java学习笔记九——构造函数、方法重写、重载
- 【慕课笔记】第七章 方法 第6节 JAVA中方法的重载
- java学习笔记---Java可变参数方法重载时要注意的几个问题
- 学习笔记-JAVA-考点10-什么情况下需要重写equals和hashcode()两个方法?
- Effective Java笔记之改写equals的通用约定
- Effective Java 学习笔记之第七条——避免使用终结(finalizer)方法
- Effective Java(避免使用最终方法、覆盖equals时请遵守通用约定)
- Java学习笔记(1):重载方法
- JAVA学习笔记32——hashCode和equals方法+set接口
- JAVA笔记2__类/封闭性/构造方法/方法的重载/匿名对象
- java笔记equals和==的区别以及intern()方法的优势
- JAVA笔记7-Object类之toString方法和equals方法
- Java学习笔记——equals()方法总结
- 【Effective Java笔记】第1条:考虑用静态工厂方法代替构造器
- java中equals和hashcode方法的重载
- Effective Java(避免使用最终方法、覆盖equals时请遵守通用约定)
- 黑马程序员-java笔记之equals和hascode方法总结。
- Java学习笔记-方法的重载
- Java之面向对象例子(三) 多态,重写,重载,equals()方法和toString()方法的重写
- Effective Java(避免使用最终方法、覆盖equals时请遵守通用约定)