• equals 方法示例
// 代码来自《Java核心技术 卷I》P167
// 父类
public class Employee{
...
public boolean equals(Object otherObject){
// a quick test to see if the objects are identical
if(this == otherObject) return true; // must return false if the explicit parameter is null
if(otherObject == null) return false; // if the classes don't match, they can't be equal
// 笔者注:子类通过super.equals方法调用到此处时,getClass()的结果是子类
if(getClass() != otherObject.getClass())
return false; // now we know otherObject is a non-null Employee
Employee other = (Employee) otherObject; // test whether the fields hava identicial values
// 笔者注:此处使用Objects.equals方法是为了防备name或hireDay可能为null的情况
return Objects.equals(name, other.name)
&& salary == other.salary
&& Objects.equals(hireDate, other.hireDate);
}
}
// 子类
// 先调用超类的equals,如果返回false,对象则不可能相等
// 如果父类中的域都相等,再比较子类的实例域
public class Manager extends Employee{
...
public boolean equals(Object otherObject){
if(!super.equals(otherObject)) return false;
// super.equals checked that this and otherObject belong to the same class
Manager other = (Manager) otherObject;
return bonus == other.bonus;
}
}
  • Java 语言规范要求 equals 方法具有以下特性:

    • 自反性:x.equals(x) 应当返回 true
    • 对称性:x.equals(y) 与 y.equals(x) 返回应当相同
    • 传递性:如果 x.equals(y) 返回 true,且 y.equals(z) 也返回 true,则 x.equals(z) 也应返回 true
    • 一致性:如果 x 与 y 引用的对象没有发生变化,则 x.eqauls(y) 也不应变化
    • 对于任意的非空引用 x,x.equals(null) 应当返回 false
  • 在上面的例子中,如果发现类型不一致,就返回 false。但同时也有许多程序员喜欢采用以下代码进行检测 if(!(otherObject instanceof Employee)) return false; 但这样没有解决 otherObject 是子类的情况(父类对象.eqaules(子类对象))下的比较问题。

  • 关于 getClass 与 instanceof 两种检测方法:

    • 如果子类能够拥有自己的相等概念,则对称性需求将强制采用 getClass 进行检测。
    • 如果由超类决定相等的概念,那么就可以使用 instanceof 进行检测,这样可以在不同子类的对象之间进行相等的比较。
  • 编写完美的 equals 方法的建议:

    1. 显式参数命名为 otherObject,稍后需要将它转换为另一个叫做 other 的变量。
    2. 检测 this 与 otherObject 是否引用同一个对象:return this == otherObject;
    3. 检测 otherObject 是否为 null,是则返回 false。
    4. 比较 this 与 otherObject 是否属于同一个类:
      • 如果 equals 的语义在每个子类中有所改变,就使用 getClass 检测:return getClass() != otherObject.getClass();
      • 如果所有的子类都拥有统一的语义,就使用 instanceof 检测:return (!(otherObject instanceof ClassName));
    5. 将 otherObject 转换为相应的类类型变量:ClassName other = (ClassName) otherObject
    6. 对所有需要比较的域进行比较。使用 == 比较基本类型域,使用 equals 比较对象域。如果所有的域都匹配,则返回 true,否则返回false。
      return field1 == other.field1
      && Objects.equals(field2, other.field2)
      && ...;

      如果在子类中重新定义 equals,就要在其中包含调用 super.equals(other)。

最新文章

  1. Redis作为消息队列服务场景应用案例
  2. TYVJ1338 QQ农场
  3. Javaweb学习随笔_JSP的九大内置对象
  4. 网络转载——java接口的概念
  5. TP框架整合Swagger UI接口文档
  6. js:数据结构笔记6--字典
  7. 手机端overflow scroll卡顿的情况
  8. Verilog HDL常用的行为仿真描述语句
  9. 使用EF6.0出现:CS0029 无法将类型“System.Data.Entity.Core.Objects.ObjectContext”隐式转换为“System.Data.Objects.ObjectContext”错误
  10. wemall app商城源码中基于PHP的通用的树型类代码
  11. HTTP与私有二进制协议之间的区别
  12. Git 简单入门(二)
  13. SpringBoot+MyBatis+MySQL读写分离
  14. vi编辑器和系统分区
  15. shiro会话管理
  16. 编辑距离12 · Edit Distance12
  17. ubuntu 16.04通过源码方式安装nginx
  18. 【转载】解决window.showModalDialog 模态窗口中location 打开新窗口问题
  19. PHP 生成类似 SqlServer NEWID() 全局唯一标识符
  20. Django - 安装wagtail

热门文章

  1. spring注解略解
  2. idea中git的运用
  3. redis RDB快照和AOF日志持久化配置
  4. ZJOI2015 幻想乡战略游戏 动态点分治_树链剖分_未调完
  5. 解决python执行cmd命令出现"XXX不是内部命令"的问题
  6. win10卸载瑞星
  7. Django入门--模板变量、过滤器及静态文件
  8. react 简单在页面中输出一段文字
  9. PL/SQL控制语句
  10. yiii 数据库备份导出