Java中对于所有对象都通用的方法之——equals

本文详细介绍了Java中Object类的equals方法,包括其通用约定、实现高质量equals方法的技巧及注意事项。通过具体示例,帮助读者理解如何正确重写equals方法。

Object:所有类的超类

Object类是Java中所有类的超类,在Java中每个类都是由它扩展来的。

尽管Object是一个具体的类,但是设计它主要是为了扩展。它所有的非final方法(equals、hasCode、toString、clone和fanalize)都有明确的通用约定(general contract),因为它们被设计成是要被覆盖(Override)的.


equals

Object类中的equals方法用于检测一个对象是否等于另外一个对象。在Object类中,这个方法将判断两个对象是否具有相同的引用。
然而,对于多数类来说,这种判断并没有什么意义。因为当判断对象是否相等时,经常需要检测两个对象状态的相等性。

通用约定 [JavaSE6]
  • 自反性。对于任何非null的引用值x,x.equals(x)必须返回true。
  • 对称性。对于任何非null的引用值x和y,如果y.equals(x)返回true时,x.equals(y)必须返回true。
  • 传递性。对于任何非null的引用值x、y和z,如果x.equals(y)返回true,并且y.equals(z)返回true时,x.equals(z)也必须返回true。
  • 一致性。对于任何非null的引用值x和y,只要equals的比较操作在对象中所用的信息没有被修改,多次调用x.equals(y)就会一致地返回true,或者一致的返回false。
  • 对于任何非null的引用值x,x.equals(null)必须返回false。
实现高质量equals的诀窍
  • 1)显示参数命名为otherObject,稍后需要将它转换成另一个叫做other的变量。
  • 2)使用==操作符检测this与otherObject是否引用同一个对象:
    if(this == otherObject) return true;
  • 3)检测otherObject是否为null,如果为null,返回false。这项检测时必要的。
    if(otherObject == null) return false;
  • 4)比较this与otherObject是否属于同于一个类。
    如果equals的语义在每个子类中有所改变,就使用getClass检测:
    if(getClass() != otherObject.getClass()) return false;
    如果所有的子类都拥有统一的语义,就使用instanceof检测:
    if(!(otherObject instanceof ClassName)) return false;
  • 5)将otherObject转换为相应的类类型变量:
    ClassName other == (ClassName) otherObject
  • 6)现在开始对所有需要比较的域进行必较了。使用==比较基本类型域,使用equals比较对象域。如果所有的域都匹配,就返回true;否则返回false。
    return field1 == other.field1&&Objects.equals(field2, other.field2)&&···;
  • 7)如果在子类中重新定义equals,就要在其中包含super.equals(other)。
for example
class Employee
{
    public boolean equals(Object otherObject)
    {
        //a quick test tot 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
        if(getClass() != otherObejct.getClass())
            return false;

        //now we know otherObject is non-null Employee
        Employee other = (Employee) otherObject;

        //test whether the fields have identical values
        return name.equals(other.name)
                && salary == other.salary
                && hireDay.equals(other.hireDay);
    }
}
class Manager extends Employee
{
    public boolean equals(Obejct 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;
    }
}
告诫
  • 覆盖equals时总要覆盖hashCode。
  • 不要企图让equals方法过于智能。
  • 不要将equals声明中的Object对象替换为其他的类型。(否则就没有覆盖Object.equals.)

未完待续
参考《Java核心技术》、《Effective Java》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值