java中如何实现一个优美的equals方法
java中的任何类都从老祖宗Object中集成了equals方法,在编程实践中应用使用equals方法判断两个对象是否相同的场景无处不在,所以我们在实现自己的类是必须重写出一个优美的equals方法。
- 首先让我们来看看java语言规范中对equals方法的说明,一个equals方法应当满足如下几个特性:
- 自反性,对任何一个非空的引用x,x.equals(x)必须返回true;
- 对称性,对任何引用x和y来说,如果x.equals(y)返回true,那么y.equals(x)也必须返回true;
- 传递性,对任何引用x、y和z,如果x.equals(y)为true,y.equals(z)为true,那么x.equals(z)也必须为true;
- 一致性,如果x和y应用的对象没有发生改变,那么对x.equals(y)的重复调用都应当返回同样的值;
- 对任何非空引用x,e.equals(null)返回false。
根据上面的6个条件,我们在重写一个equals方法时,可以遵循方法步骤:
- 将显示参数命名为otherObject,稍后转化为目标类型并命名为other;
- 检查this和otherObject是否相同;
- 检查otherObject是否为空,为空则返回false;
- 检查this和otherObject类型是否相同;
- 将otherObject转化为目标类型,并命名为other;
- 对类型中定义的属性进行比较,如果是基础数据类型使用==,如果是引用类型使用equals()。
其中第4条在父子类之间进行比较是需要注意。如果父类中定义的equals中的功能在子类中发生了变化,使用if(this.getClass() != otherObject)进行类型比较;如果父类中equals中的功能在子类中发生了变化,使用if(!(otherObject instanceof this.getClass()))进行比较。例如,Employee类中name和salary两个属性,Manager类继承Employee,还拥有bonus属性。Employee中重写的equals方法比较name和salary是否相同,Manager继承Employee的equals方法后并没有再次进行重写,那么再进行Employee和Manager类的对象的equals比较时,使用 if(!(otherObject instanceof this.getClass()))return false;如果Manager中除了比较name和salary外还要比较bonus,即Manager要重写一个自己的equals方法,那么使用if(this.getClass()!=otherObject.getClass())return false;具体实现可以参考如下代码:
public boolean equals(Object otherObject){ //a quick test to see if the object are identical if(this == otherObject){ return true; } //must return false if the explicit param is null if(otherObject == null){ return false; } //if the class des‘t match, they cannot be equal if(this.getClass() != otherObject.getClass()){ return false; } //now we the the otherObject is non-null Employee Employee other = (Employee)otherObject; //test whether the fields hava identical values return name.equals(other.name) &&salary == other.salary &&hireDay == other.hireDay; }
此处有一注意事项,在实现自己的equals方法时,如果声明为public boolean equals(Employee otherObject),即显示参数的类型不是Object类型,那么此方法不是继承自Object对象,而是Employee自己定义的一个方法。从Object继承的public boolean equals(Object otherObject)在java术语中交Overriding,自己定义的public boolean equals(Employee otherObject)叫Overloading。前者在运行期间动态绑定,后者在编译期间静态绑定。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。