Blog
It's a Wonderful Life
如何写出一个相对完善的equals方法
在java中,检测两个对象是否相同的函数为equals(Object obj)
,在大多数情况下这个函数能够满足检测的需要,但是,在检测两个自定义类的对象是否相同的时候却往往需要对这个方法进行重写(overwrite)。因为即使是拥有相同状态的两个自定义对象,如果存放在内存中的不同区域,equals
方法也会返回false
。
下面就给出写出一个相对完善的equals
方法的建议。
- 显式参数命名为
otherObject
,稍后要把它转为一个other
对象。 -
检测
this
是否与otherObject
为同一个对象。if (this == otherObject) return true;
-
检测
otherObject
是否为null
。if (otherObject == null) return false;
-
比较
this
与otherObject
是否同属于一个类,如果子类中的equals
语义与父类中不同,就用getClass()
检测。if (this.getClass() != otherObject.getClass()) return false;
如果所有的子类都拥有同样的语义,就使用
instanceof
检测。if (! (otherObject instanceof ClassName)) return false;
-
现在可知,
otherObject
与this
同属于一个类,可以把它转换为相应的对象变量。ClassName other = (ClassName) otherObject;
- 现在可以开始对所有需要比较的域进行比较了,使用
==
比较基本类型域,使用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
标签,这样,如果函数签名不一致,编译器会自动报错。