重写 equals 方法

来源:互联网 发布:淘宝联盟助手机版 编辑:程序博客网 时间:2024/05/18 01:20

-- Start

重写 equals 方法是一件很令人头疼的事情, Java 语言规范要求 equals 方法具有下面的特性:

1. 自反性: x.equals(x)应该返回true.2. 对称性: 如果x.equals(y)返回true, 那么y.equals(x)也应该返回true.3. 传递性: 如果x.equals(y)返回true, y.equals(z)返回true, 那么x.equals(z)也应该返回true.4. 一致性: 如果对象没有变化, 反复调用equals方法应该返回相同的结果.5. x.equals(null) 应该返回false.

看上去很简单, 但是在涉及继承的时候, 稍有不慎就违反了对称性, 下面是一个例子.

public class Test {public static void main(String[] args) {Poeple p = new Poeple();p.setName("ZhangSan");p.setAge(20);Student s = new Student();s.setName("ZhangSan");s.setAge(20);s.setID(1);System.out.println("p.equals(s) == " + p.equals(s));System.out.println("s.equals(p) == " + s.equals(p));}}class Poeple {private String name;private int age;@Overridepublic boolean equals(Object otherObject) {if (this == otherObject)return true;if (otherObject == null)return false;if (!(otherObject instanceof Poeple))return false;Poeple other = (Poeple) otherObject;return name.equals(other.name) && age == other.age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}class Student extends Poeple {private int ID; // 学号@Overridepublic boolean equals(Object otherObject) {if (!super.equals(otherObject))return false;if (!(otherObject instanceof Student))return false;Student other = (Student) otherObject;return ID == other.ID;}public int getID() {return ID;}public void setID(int iD) {ID = iD;}}
结果如下:

p.equals(s) == trues.equals(p) == false

出现这种情况的原因是超类与子类有不同的比较规则, 实际的情况有以下两种:

1. 由超类决定是否相等, 如: 不管是学生还是老师, 每个人都有身份证号, 由身份证号来确定两个人是否是同一个人, 下面是一个范例程序.

class Poeple {private int ID;private String name;// 由于超类决定是否相等, 可以将equals方法设置为final, 禁止子类重写@Overridepublic final boolean equals(Object otherObject) {if (this == otherObject)return true;if (otherObject == null)return false;if (!(otherObject instanceof Poeple))return false;Poeple other = (Poeple) otherObject;return ID == other.ID;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getID() {return ID;}public void setID(int iD) {ID = iD;}}class Student extends Poeple {// Student 可以有自己的域}class Teacher extends Poeple {// Teacher 可以有自己的域}

2. 子类有自己的相等概念, 下面是一个范例程序.

class Poeple {private String name;private int age;@Overridepublic boolean equals(Object otherObject) {if (this == otherObject)return true;if (otherObject == null)return false;if (getClass() != otherObject.getClass()) // 注意此处, 我们不能通过 instanceof 来判断return false;Poeple other = (Poeple) otherObject;return name.equals(other.name) // 使用 equals 对象域&& age == other.age; // 使用 == 比较基本类型}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}class Student extends Poeple {private int grade;@Overridepublic boolean equals(Object otherObject) {if (!super.equals(otherObject)) // 此处需要调用父类的 equals 方法return false;Student other = (Student) otherObject;return grade == other.grade;}}


从上面的例子可以看出, 想写出一个完美的 equals 还是很不容易的, 幸运的是 Apache Common 包有个 EqualsBuilder 类, 它能帮助我们很容易的实现 equals 方法.

--更多参见:Java 精萃
-- 声 明:转载请注明出处
-- Last Updated on 2012-05-18
-- Written by ShangBo on 2012-05-18
-- End


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 校园网翻不了墙怎么办 xp网站证书错误怎么办 wifi一直掉线怎么办 太累了头晕怎么办 大专证没有认证怎么办 学生信息怎么办忘了 中专对口大专考不上怎么办 学历认证待校对怎么办 毕业证上没照片怎么办 怎么办学历学位认证证明 教育部学历学位认证怎么办 兵役登记被注册怎么办 学信网手机号忘了怎么办 注销手机号了学信网怎么办 学信网手机换了怎么办 学籍不在籍结业怎么办 电教馆的幼师证怎么办 中考不够建档线怎么办 医保漏交一年怎么办 南通图书馆怎么办饭卡 工商银行卡坏了怎么办 北京一卡通丢了怎么办 甲状腺右叶结节怎么办 ca证书掉了怎么办 地税ca丢了怎么办 南京乘车卡丢失怎么办 老干妈瓶盖打不开怎么办 金陵图书馆书丢失怎么办 幼师资格证丢了怎么办 双证毕业没有怎么办 幼师面试没特长怎么办 资格证到6年没换怎么办 中央巡视组走了怎么办 校园招聘学生违约怎么办 应届毕业生考上公务员档案怎么办 移动硬盘弹不出来怎么办 录音笔电池坏了怎么办 上不吃大厕怎么办 跨考研究生面试怎么办 手机信息查重怎么办 闲鱼不予申诉怎么办