第八条——覆盖equals方法时需遵守的通用约定
1)自反性
对于任何非null的引用值x,x.equals(x)必须返回true。---这一点基本上不会有啥问题
2)对称性
对于任何非null的引用值x和y,当且仅当x.equals(y)为true时,y.equals(x)也为true。
JDK中就有这样的错误。如java.sql.Timestamp对java.util.Date进行了扩展,并且增加了nanoseconds域。Timestamp的equals方法就违反了对称性。
下面我们来分析下这个方法
//Date.java
public boolean equals(Object obj) {
return obj instanceof Date && getTime() == ((Date) obj).getTime();
} //Timestamp.java
public boolean equals(java.lang.Object ts) {
if (ts instanceof Timestamp) {
return this.equals((Timestamp)ts);
} else {
return false;
}
} public boolean equals(Timestamp ts) {
if (super.equals(ts)) {
if (nanos == ts.nanos) {
return true;
} else {
return false;
}
} else {
return false;
}
}
比如说Date d ; Timestamp t.那么d.equals(t)==true,但是从Timestamp的equals方法可以看到,t.equals(d)==false
3)传递性
对于任何非null的引用值x、y、z。如果x.equals(y)==true,y.equals(z)==true,那么x.equals(z)==true。
这一条主要是针对子类增加了新的属性导致的.
我们可以再一个抽象的类的子类中增加新的属性,而不会违反equals约定。只要不能直接创建超类的实例,上述几种约定的问题就不会出现。
4) 一致性
对于任何非null的引用值x和y,只要equals的比较操作在对象所用的信息没有被修改,那么多次调用x.eqals(y)就会一致性地返回true,或者一致性的返回false。
5)非空性
所有比较的对象都不能为空。
许多类的equals方法都通过一个显示的null测试来防止这种现象,如下所示:
@override
public boolean equals(Object o) {
if(o==null) {
return false;
}
.........
}
其实没有必要,因为为了测试equals参数的等同性,equals方法必须先把参数转换成适当的类型,以便可以调用它的访问方法,或者域。在进行转换前,equals方法必须使用instanceof操作符,检查其参数是否为正确的类型,如下所示:
@override
public boolean equals(Object o) {
if(!(o instanceof MyType)) {//如果o==null,这一步就返回false
return false;
}
.........
}
综上所述,得出 以下实现高质量equals方法的诀窍
1. 使用==操作符检查“参数是否为这个对象的引用”。。这只不过是一种性能优化,如果比较操作可能跟昂贵,就值得这么做。
2. 使用instanceof操作符检查“参数是否为正确的类型”
3. 把参数转换成正确的类型
4. 对于该类的每个“关键”域,检查参数中的域是否与该对象中对应的域匹配。
注意域的比较顺序可能会影响equals方法的性能,为了获得最佳的性能,应该最先比较最不可能一致的域或者开销最小的域。
5. 当完成equals方法时,一定要检查是否符合:对称性、传递性、一致性
6. 覆盖equals方式时总是要覆盖hashCode方法
7. 不要企图让equals方法过于智能
8.不要把equals方法声明中的参数Object类型替换为其他类型(用@override标签保证此点)
第八条——覆盖equals方法时需遵守的通用约定的更多相关文章
- 重载equals方法时要遵守的通用约定--自反性,对称性,传递性,一致性,非空性
本文涉及到的概念 1.为什么重载equals方法时,要遵守通用约定 2.重载equals方法时,要遵守哪些通用约定 为什么重载equals方法时,要遵守通用约定 Object类的非final方法都 ...
- 覆盖equals方法时请遵守通用约定
覆盖equals方法时请遵守通用约定 覆盖equals方法看起来很简单,但是有许多覆盖方式会导致错误,并且后果很严重.最容易避免这种类问题的方法就是不覆盖equals方法,在这种情况下,类的每个实 ...
- 第九条:覆盖equals方法时总要覆盖hashCode方法
Object类的hashCode方法: public native int hashCode(); 是一个本地方法. 其中这个方法的主要注释如下: Whenever it is invoked o ...
- 【Java实战】源码解析为什么覆盖equals方法时总要覆盖hashCode方法
1.背景知识 本文代码基于jdk1.8分析,<Java编程思想>中有如下描述: 另外再看下Object.java对hashCode()方法的说明: /** * Returns a hash ...
- Effective Java 第三版——10. 重写equals方法时遵守通用约定
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- [改善Java代码]覆写equals方法时不要识别不出自己
建议45: 覆写equals方法时不要识别不出自己 我们在写一个JavaBean时,经常会覆写equals方法,其目的是根据业务规则判断两个对象是否相等,比如我们写一个Person类,然后根据姓名判断 ...
- Effective Java 第三版——11. 重写equals方法时同时也要重写hashcode方法
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- 使用equals方法时,要注意
这是我在项目中犯的一个低级错误: 使用equals方法时,要注意这个方法是boolean java.lang.String.equals(Object anObject)传递的是Object,所以传任 ...
- 为什么重写equals方法时,要求必须重写hashCode方法?
1 equals方法 Object类中默认的实现方式是 : return this == obj .那就是说,只有this 和 obj引用同一个对象,才会返回true. 而我们往往需要用equ ...
随机推荐
- JSON字符串序列化与反序列化浅试
一.添加引用(using Newtonsoft.Json.Linq;) 二. 1.生成json字符串源码 List<string> list = new List<string> ...
- JSP中两种模式的总结
运用JSP/Servlet实现的Web动态交互,主要采用: 模式一:JSP+JavaBean 链接:http://wxmimperio.coding.io/?p=155 模式二;JSP+Servlet ...
- 【HDU2222】Keywords Search(AC自动机)
Problem Description In the modern time, Search engine came into the life of everybody like Google, B ...
- LED七彩变色灯的制作
LED变色灯是一种新型灯泡.它的外形与一般乳白色白炽灯泡相同,但点亮后会自动按一定的时间间隔变色.循环地发出青.黄.绿.紫.蓝.红.白色光.它适用于家庭生日派对.节日聚会.过节过年,给节日添加欢乐气氛 ...
- Android 一个页面上下两个ListView的页面显示
Android 一个页面上下两个ListView,当上面的ListView过长时,下面的List基本没有了滑动空间,查阅网上资料,解决办法基本是采用ScrollView做页面滑动,notifyData ...
- leetcode面试准备:Multiply Strings
1 题目 Given two numbers represented as strings, return multiplication of the numbers as a string. Not ...
- 14.8.3 Physical Row Structure of InnoDB Tables InnoDB 表的物理行结构
14.8.3 Physical Row Structure of InnoDB Tables InnoDB 表的物理行结构 一个InnoDB 表的物理行结构取决于在创建表指定的行格式 默认, Inno ...
- .net 开源项目
.NET开发人员值得关注的七个开源项目 [IT168技术分析]微软近几年在.NET社区开源项目方面投入了相当多的时间和资源,不禁让原本对峙的开源社区阵营大吃一惊,从微软.NET社区中的反应来看,微软. ...
- 一起啃PRML - Preface 前言
一起啃PRML - 前言 Preface @copyright 转载请注明出处 http://www.cnblogs.com/chxer/ PRML,Pattern Recognition and M ...
- java基础(五)
这里有我之前上课总结的一些知识点以及代码大部分是老师讲的笔记 个人认为是非常好的,,也是比较经典的内容,真诚的希望这些对于那些想学习的人有所帮助! 由于代码是分模块的上传非常的不便.也比较多,讲的也是 ...