下文笔者讲述 Java 中重写equals方法的相关简介及说明,如下所示
equals方法简介
在java的顶级基类中有一个对象Object类拥有一个方法equals
equals方法的功能:
用于比较两个对象是否完全相等,当两个对象完全相等时,则返回true
Object类中equals方法的源码
java中,Object类中有一个equals方法:
public boolean equals(Object obj) {
return (this == obj);
}
从以上代码中,我们可以看出Object中的equals方法
对比的为两个对象的引用地址
注意事项:
在一些自定义对象中,我们通常会重写equals方法
并采用自身定义的对象是否相同的界定规则
重写equals方法注意事项
覆盖equals方法须遵循
自反性 (reflexive)
对称性(symmetric)
传递性(transitive)
一致性(consistent)
非null对象与null进行equals比较必为false等约定。
自反性:a!=null,则a.equals(a)返回true.
对称性:a!=null,b!=null,则a.equals(b) == b.equals(a).
传递性:a!=null,b!=null,c!=null,如果a.equals(b) == b.equals(c),这a.equals(c).
一致性:a!=null,b!=null,如果a,b没有被修改,那么不管调用多少次equals,返回的结果始终只有一个.
非null对象与null进行equals比较必为false.
重写equals方法的步骤
使用“==”操作符检查参数是否是这个对象的引用。
检查参数是否为空。
检查参数类型是否匹配。
把参数转换为正确的类型。
对于类中需要进行逻辑判断的属性,检查参数的属性是否与这个对象的属性相同(比较属性也使用对于属性所属类型的equals方法)。
编写完成后,验证是否满足对称、传递、一致等特性。
写equals方法需要注意的地方
覆盖equals时总要覆盖 hashCode 方法,避免一些预想不到的错误。
不要将equals声明中的Object对象替换为其他类型,因为参数不同的相同方法名是重载而不是重写,这可能让程序运行结果变得难以预料。
例:
重写一个User对象中的equals方法
当用户名和手机号都相同时候,则认为两个对象是同一个用户
此时我们需重写equals和hashCode
并遵循自反、对称、传递、一致、null比较等测试
package com.java265;
public class User {
/** 用户名 */ private String name;
/** 手机号 */ private String phone;
public User(String name, String phone) {
super();
this.name = name;
this.phone = phone;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((phone == null) ? 0 : phone.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
//1.使用“==”操作符检查参数是否是这个对象的引用
if (this == obj){
return true;
}
//2.检查参数是否为空
if (obj == null){
return false;
}
//3.检查参数类型是否匹配
if (getClass() != obj.getClass())
return false;
//4.把参数转换为正确的类型
User other = (User) obj;
//5.对于类中需要进行逻辑判断的属性,检查参数的属性是否与这个对象的属性相同
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (phone == null) {
if (other.phone != null)
return false;
} else if (!phone.equals(other.phone))
return false;
return true;
}
public static void main(String[] args) {
System.out.println("test begin");
User a = new User("a", "139xxxxxxxx");
User b = new User("a", "139xxxxxxxx");
User c = new User("a", "139xxxxxxxx");
//自反性
assert a.equals(a);
//传递性
assert a.equals(b) == b.equals(c) ? a.equals(c) : false;
//对称性
boolean result = a.equals(b);
assert result == b.equals(a);
//一致性
for(int i = 0; i < 66; i++){
assert result == a.equals(b);
}
//非null对象与null进行equals比较必为false
assert a.equals(null) == false;
System.out.println("test end");
assert false;
}
}
注意事项:
代码启动时,需在 JVM 中加上 -ea选项 开启断言