第八条——覆盖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 ...
随机推荐
- Junit 源码剖析(一)
采用Junit4.8.2分析Junit实现架构 源码架构两个大包:junit包 org包 首先分析org.junit.runners.model包下的几个类 org.junit.runners.mod ...
- [译]36 Days of Web Testing(四)
Day 19: UX 用户体验 Why ? 最近UX变得越来越火,用户提现往往会直接联想到易用性和设计. 在我看来,UX不仅仅是这两点.UX, User Experience ,对我而言,不单单是产 ...
- netsat -ano 查看已占用的端口以及tomcat出现端口被占或者启动失败问题
A.在DOS命令下:输入netstat -ano——回车,可以查看已占用的端口,记下端口的PID,然后打开任务管理器,点查看,选择列,勾选PID确定,找到对应的PID,结束进程,如果结束不了或者结束后 ...
- For Aisha(阿伊莎)
相见时难别亦难,东风无力百花残.by:昂思多,20160524 跟你在一起,没有拘束感,完全就像是在跟亲人对话. 很喜欢这种感觉 虽然才认识不到10天,却就像是认识了好几年的老朋友 真的喜欢叫你“阿伊 ...
- 【Java】整理关于java的String类,equals函数和比较操作符的区别
初学 Java 有段时间了,感觉似乎开始入了门,有了点儿感觉但是发现很多困惑和疑问而且均来自于最基础的知识折腾了一阵子又查了查书,终于对 String 这个特殊的对象有了点感悟大家先来看看一段奇怪的程 ...
- socket.io发送给指定的客户端
http://www.cnblogs.com/ajccom/archive/2013/07/18/3197809.html http://stackoverflow.com/questions/100 ...
- 10.在Global全局文件中的Application_BeginRequest示例
只要有人访问本网站,都要执行全局文件的Application_BeginRequest事件.因此我们可以防盗链. 示例要求:凡不是网站本机登录的都给客户端提示,用图片显示. 分析:由于网页在加载时不是 ...
- once
var once = function(obj, evtType, handler) { var f = function() { //console.log(arguments) handler.a ...
- 【Cocos2d-x JavaScript Binding】
Cocos2d-x JavaScript Binding结合CocosBuilder跨平台游戏开发简明教程http://www.cocoachina.com/applenews/devnews/201 ...
- Android 国内镜像
Android SDK官网国内很难直接访问,除了FQ/VPN等方法还是很不方便. 原有的Android SDK直接下载因http://dl-ssl.google.com/android/reposit ...