您的位置 首页 java

Effective Java代码规则之十:覆盖equals时请遵守通用约定

1、解释

我们知道,Object类提供了equals方法:

public boolean equals(Object obj) {
 return (this == obj);
}
 

实现了对象地址的比较。也就是判断是否指向了同一对象。下列情况下,我们需要覆盖equals方法:

  • 当需要判断是否逻辑相等,且超类还没有覆盖equals

这通常属于“值类”(value class)的情形。值类仅仅是一个表示值的类,例如Integer或者String 。程序员在利用equals方法来比较值对象的引用时,希望知道它们在逻辑上是否相等,而不是想了解它们是否指向同一个对象。String和八大基本类型的封装类都已经覆盖了equals方法。

在覆盖equals 方法的时候,必须要遵守它的通用约定:

  • 自反性 (reflexive):对于任何非null的引用值x,x.equals(x)必须返回true
  • 对称性(symmetric):对于任何非null的引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)必须返回true
  • 传递性(transitive):对于任何非null的引用值x、y和z,如果x.equals(y)为true,并且y.equals(z)也返回true,那么x.equals(z)也必须返回true
  • 一致性(consistent):对于任何非null的引用值x和y,只要equals的比较操作在对象中所用的信息没有被修改,多次调用x.equals(y)就会一致地返回true,或者一致地返回 false
  • 非空性(Non-nullity):对于任何非null的引用值, x.equals(null)必须返回false

2、实现高质量equals的方法

  • 使用==操作符检查”参数是否为这个对象的引用”
  • 使用 instanceof 操作符检查”参数是否为正确的类型”
  • 对于类中的关键属性,检查参数传入对象的属性是否与之相匹配
  • 编写完equals方法后,问自己它是否满足对称性、传递性、一致性
  • 重写equals时总是要重写 hashCode
  • 不要将equals方法参数中的Object对象替换为其他的类型,在重写时不要忘掉@ Override 注解

3、最佳实践

在实际工作中,覆盖equals方法比较麻烦,通常我们使用IDE工具自带的生成equals功能:

 private String loginId;
 private String password;
 private String name;
 

例如有以上属性的value object,使用工具生成的代码如下:

 @Override
 public boolean equals(Object obj) {
 if (this == obj)
 return true;
 if (obj == null)
 return false;
 if (getClass() != obj.getClass())
 return false;
 ExampleBean other = (ExampleBean) obj;
 if (loginId == null) {
 if (other.loginId != null)
 return false;
 } else if (!loginId.equals(other.loginId))
 return false;
 if (name == null) {
 if (other.name != null)
 return false;
 } else if (!name.equals(other.name))
 return false;
 if (password == null) {
 if (other.password != null)
 return false;
 } else if (!password.equals(other.password))
 return false;
 return true;
 }
 

文章来源:智云一二三科技

文章标题:Effective Java代码规则之十:覆盖equals时请遵守通用约定

文章地址:https://www.zhihuclub.com/174167.shtml

关于作者: 智云科技

热门文章

网站地图