前言 我们都知道Object类中的equals方法用于检测一个对象是否等于另一个对象。在没有重写equals方法之前,这个方法将
判断俩个对象是否具有相同的引用
。对于多数类来说,这种判断并没有什么意义。我们通常需要检测俩个对象状态的相等性。比如下面的学生对象,如果俩个学生对象的姓名、学号都相同,就认为他们是相等的。
public class Student {
private String name;
private String studentNo;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStudentNo() {
return studentNo;
}
public void setStudentNo(String studentNo) {
this.studentNo = studentNo;
}
}
java语言规范要求equals方法具有下面的特性:
- 自反性:对于任何非空引用o,
o.equals(o)
应该返回true。 - 对称性:对于任何引用x和y,当且仅当
y.equals(x)
返回true,x.equals(y)
也应该返回true
。 - 传递性:对于任何引用x、y和z,如果
x.equals(y)
为true,y.equals(z)
为true,x.equals(z)
也应该返回true - 一致性:如果x和y引用的对象没有发生变化,反复调用
x.equals(y)
应该返回同样的结果 - 对于任何非空引用x,
x.equals(null)
应该返回false
重写对象equals方法的建议,注意看代码注释,重写了Student对象的equals方法
@Override
public boolean equals(Object otherObject) {
// 1、检测this与otherObject是否引用同一个对象
if (this == otherObject){
return true;
}
// 2、检测otherObject是否为null,如果为null返回false
if (null == otherObject){
return false;
}
// 3、比较this与otherObject是否属于同一个类 。这里有两种方法进行检测,在文字最后会解释具体应该如何使用
// 这里先不考虑类继承的情况,演示使用getClass进行检测
if (getClass()!=otherObject.getClass()){
return false;
}
// 4、将otherObject转换为相应的类类型变量,对需要比较的域进行比较。使用==比较基本数据域,equals比较对象域。都匹配则返回true。
Student other = (Student) otherObject;
return Objects.equals(name,other.name) && Objects.equals(studentNo,other.studentNo);
}
比较this与otherObject是否属于同一个类 。这里有两种方法进行检测,第二种方法是什么?应该使用哪一种
// 第二种检查this与otherObject是否属于同一个类的方法
if (otherObject instanceof Student){
return true;
}
通常在不涉及继承子父类的情况下,由于因对称性的要求将强制使用getClass进行检测
如果不熟悉 instanceof 关键字的作用可以查看这篇文章
根据下面的规则来看看适合使用哪种方式
调用Student类的
equals
方法,检测重写后的equals方法
// 演示重写后的equals方法作用。
public static void main(String[] args) {
// new出俩个属性值相同的Student对象变量
Student student = new Student();
student.setName("wali");
student.setStudentNo("NO1001");
Student studentSecond = new Student();
studentSecond.setName("wali");
studentSecond.setStudentNo("NO1001");
System.out.println("student.equals(studentSecond):"+student.equals(studentSecond)); // true
}
我们看到重写后的equals方法已经返回true了,说明重写后的equals方法没有问题