Blog

It's a Wonderful Life

如何写出一个相对完善的equals方法

2017-03-14 17:56 Posted in Learn with Java

在java中,检测两个对象是否相同的函数为equals(Object obj),在大多数情况下这个函数能够满足检测的需要,但是,在检测两个自定义类的对象是否相同的时候却往往需要对这个方法进行重写(overwrite)。因为即使是拥有相同状态的两个自定义对象,如果存放在内存中的不同区域,equals方法也会返回false

下面就给出写出一个相对完善的equals方法的建议。

  1. 显式参数命名为otherObject,稍后要把它转为一个other对象。
  2. 检测this是否与otherObject为同一个对象。

     if (this == otherObject) return true;
    
  3. 检测otherObject是否为null

     if (otherObject == null) return false;
    
  4. 比较thisotherObject是否同属于一个类,如果子类中的equals语义与父类中不同,就用getClass()检测。

     if (this.getClass() != otherObject.getClass()) return false;
    

    如果所有的子类都拥有同样的语义,就使用instanceof检测。

     if (! (otherObject instanceof ClassName)) return false;
    
  5. 现在可知,otherObjectthis同属于一个类,可以把它转换为相应的对象变量。

     ClassName other = (ClassName) otherObject;
    
  6. 现在可以开始对所有需要比较的域进行比较了,使用==比较基本类型域,使用equals比较对象域。如果所有的域都匹配,返回true,反之,返回false
if (this.field1 == other.field1 && this.field2.equals(other.field2)...)
{
	return true;
}
else
{
	return false;
}

如果子类中对equals方法进行了重写,就要先调用super.equals(otherObject)

有一个常见错误是写成了equals(ClassName obj)而不是equals(Object obj),这样实际上并没有对Object类的equals方法进行重写,而是自己定义了一个新的方法。避免出现这样的错误可以在equals方法声明之前加上@Override标签,这样,如果函数签名不一致,编译器会自动报错。