重写equals方法的建议!

985 阅读2分钟

前言 我们都知道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 关键字的作用可以查看这篇文章

根据下面的规则来看看适合使用哪种方式 image.png 调用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方法没有问题

image.png