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方法时需遵守的通用约定的更多相关文章

  1. 重载equals方法时要遵守的通用约定--自反性,对称性,传递性,一致性,非空性

    本文涉及到的概念 1.为什么重载equals方法时,要遵守通用约定 2.重载equals方法时,要遵守哪些通用约定   为什么重载equals方法时,要遵守通用约定 Object类的非final方法都 ...

  2. 覆盖equals方法时请遵守通用约定

    覆盖equals方法时请遵守通用约定   覆盖equals方法看起来很简单,但是有许多覆盖方式会导致错误,并且后果很严重.最容易避免这种类问题的方法就是不覆盖equals方法,在这种情况下,类的每个实 ...

  3. 第九条:覆盖equals方法时总要覆盖hashCode方法

    Object类的hashCode方法: public native int hashCode();   是一个本地方法. 其中这个方法的主要注释如下: Whenever it is invoked o ...

  4. 【Java实战】源码解析为什么覆盖equals方法时总要覆盖hashCode方法

    1.背景知识 本文代码基于jdk1.8分析,<Java编程思想>中有如下描述: 另外再看下Object.java对hashCode()方法的说明: /** * Returns a hash ...

  5. Effective Java 第三版——10. 重写equals方法时遵守通用约定

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  6. [改善Java代码]覆写equals方法时不要识别不出自己

    建议45: 覆写equals方法时不要识别不出自己 我们在写一个JavaBean时,经常会覆写equals方法,其目的是根据业务规则判断两个对象是否相等,比如我们写一个Person类,然后根据姓名判断 ...

  7. Effective Java 第三版——11. 重写equals方法时同时也要重写hashcode方法

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  8. 使用equals方法时,要注意

    这是我在项目中犯的一个低级错误: 使用equals方法时,要注意这个方法是boolean java.lang.String.equals(Object anObject)传递的是Object,所以传任 ...

  9. 为什么重写equals方法时,要求必须重写hashCode方法?

    1 equals方法 Object类中默认的实现方式是  :   return this == obj  .那就是说,只有this 和 obj引用同一个对象,才会返回true. 而我们往往需要用equ ...

随机推荐

  1. asp.net mvc jqgrid 同一个页面查询不同的表,jqgrid显示不同表的表头和数据并且分页

    基于我上一篇文章<a href="http://www.cnblogs.com/alasai/p/4765756.html">asp.net mvc excel导入&l ...

  2. Hadoop 学习笔记 (十) hadoop2.2.0 生产环境部署 HDFS HA Federation 含Yarn部署

    其他的配置跟HDFS-HA部署方式完全一样.但JournalNOde的配置不一样>hadoop-cluster1中的nn1和nn2和hadoop-cluster2中的nn3和nn4可以公用同样的 ...

  3. Illustrator软件中eps和ai格式的区别

    转自Illustrator软件中eps和ai格式的区别 AI是ILL特有的格式,EPS格式是在排版领域经常使用的格式.AI中的位图图像是用链接的方式存储,EPS格式则将位图图像包含于文件中.对于含有相 ...

  4. 【HDU3065】 病毒侵袭持续中(AC自动机)

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...

  5. Qt动画与Qt坐标小记

    Qt动画 转载自: <http://jingyan.baidu.com/article/154b46315757b628ca8f4116.html> 和  <http://blog. ...

  6. SQL servere 范式、事务

    一.数据库范式: 1.构造数据库必须遵循一定的规则.在关系数据库中,这种规则就是范式. 范式是符合某一种级别的关系模式的集合.数据库中的关系必须满足一定的要求,即满足不同的范式. 满足最低要求的范式是 ...

  7. (转载)mysqli使用prepared语句

    (转载)http://kaozjlin.iteye.com/blog/890855 mysqli函数库支持prepared语句的使用.它们对于在执行大量具有不同数据的相同查询时,可以提高执行速度.它们 ...

  8. Linux下的各种软件安装方法汇总

    1 RPM包 1.1 安装 RPM包就像Windows的EXE安装文件一样,各种文件都已经编译好了,并进行了打包,哪一个文件应该放在哪一个目录下都指定好了,安装非常方便,在图形界面里你只需要双击就能自 ...

  9. iOS 多线程学习笔记 —— NSThread

    本文复制.参考自文章:iOS多线程编程之NSThread的使用  ,主要为了加强个人对知识的理解和记忆,不做他用.原作者声明: 著作权声明:本文由http://blog.csdn.net/totogo ...

  10. std::numeric_limits<int>::max() error C2589: '(' : illegal token on right side of '::' 解决办法

    int max =std::numeric_limits<int>::max();     根据错误提示: f:\code\cpp\webspider\main.cpp(47) : war ...