Java教程

【Effective Java 10.6】覆盖 equals 时请遵守通用约定 —— 写出高质量 equals 方法的诀窍

本文主要是介绍【Effective Java 10.6】覆盖 equals 时请遵守通用约定 —— 写出高质量 equals 方法的诀窍,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1. 实现高质量 equals 方法的诀窍

  1. 使用 == 操作符检查 ”参数是否为这个对象的引用“。如果是,则返回 true。这只是一种性能优化。引用相同,则必定相等,无需进行后续对值的比较。
  2. 使用 instanceof 操作检查 ”参数是否为正确的类型“。如果不是,则返回 false。一般来说,所谓 ”正确的类型“ 是指 equals 方法所在的那个类。某些情况下,是指该类所实现的某个接口。如果类实现的接口改进了 equals 约定,允许在实现了该接口的类之间进行比较,那么就使用接口。接口集合如 Set、List、Map 和 Map.Entry 具有这样的特性
  3. 把参数转换成正确的类型。因为转换之前进行过 instanceof 测试,所以能确保成功。
  4. 对于该类中的每一个 ”关键“ (significant) 域,检查参数中的域是否与该对象中对应的域相匹配。如果这些测试全部成功,则返回 true;否则返回 false。如果第 2 步中的类型是一个接口,就必须通过接口方法访问参数中的域;如果该类型是一个类,也许就能直接访问参数中的域,这要取决于它们的可访问性。
    • 对于既不是 float 也不是 double 类型的基本类型域。可以使用 == 操作符进行比较
    • 对于对象引用域,可以递归地调用 equals 方法;对于 float 域 和 double 域,可以使用 Float.compare(float a, float b)Double.compare(double a, double b)
    • 对于数组类型,可以使用 Arrays.equals 进行比较
  5. 在编写完 equals 方法之后,应该问自己三个问题:它是否符合对称性、传递性、一致性。并且编写单元测试来检验这些特性。

2. 覆盖 equals 时的建议

  • 覆盖 equals 时总是要覆盖 hashCode
  • 不要企图让 equals 方法过于只能
  • 不要将 equals 声明中的 Object 对象替换为其他的类型。

3. 使用第三方库

编写和测试 equals 和 hashCode 方法都是十分繁琐的,得到的代码也很琐碎。代替这些手工编写和测试这些方法的最佳途径,就是使用一些自动生成代码的框架。如 Google 开源的 AutoValue 框架、Project Lombok、Immutables等,他会自动替换生成这些方法,通过类中的单个注解就能触发。在大多数情况下,它们生成的 equals 和 hashCode 方法与我们手工编写的方法基本一致。

此外,还可以使用 IDE 自动生成的 equals 和 hashCode 方法,但得到的源代码更加冗长。

这篇关于【Effective Java 10.6】覆盖 equals 时请遵守通用约定 —— 写出高质量 equals 方法的诀窍的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!