一、equals()方法的基本概念
在Java语言中,equals()方法是比较两个对象是否相等的方法。Object类中的默认实现是比较两个对象的引用是否相等。但是,对于我们自定义的类,需要覆盖equals()方法,根据实际需求进行比较。一般来说,比较的内容包含对象的属性,也可以考虑对象的指向等其他特殊情况。
Java语言规定:如果两个对象使用equals()方法比较相等,那么两个对象的hashCode()方法的返回值必须相等。
public boolean equals(Object obj) { if (obj == null) { return false; } if (!this.getClass().equals(obj.getClass())) { return false; } if (this == obj) { return true; } YourClass yourClass = (YourClass) obj; //比较两个对象是否相等 return this.property1 == yourClass.property1 && this.property2.equals(yourClass.property2); }
二、重写equals()方法的细节
1、先确认equals()方法的契约
在自定义类中覆盖equals()方法时,首先要沟通好同事之间使用这个方法的意义。例如,这里的"相等"是指什么?在定义相等的时候,往往也定义了相同的hashCode(),因此它们是相等的。在选择相等的概念时,需要注意的是如何使类在“集合框架”和其他Java库的所有客户端中表现良好。
2、遵守自反性、对称性、传递性、一致性和非空性
在实现equals()方法时,需要遵守以下五项规则:
- 自反性:x.equals(x)始终返回true。
- 对称性:x.equals(y)与y.equals(x)的结果应该相同,无论x、y的值如何。
- 传递性:如果x.equals(y)返回true,y.equals(z)返回true,那么x.equals(z)也应该返回true。
- 一致性:如果x.equals(y)返回true,那么多次调用x.equals(y)的结果应该始终为true或为false。
- 非空性:x.equals(null)始终返回false。
3、使用getClass()检查属性的类型
在具有继承性的类中,如果没有getClass()方法,equals()方法可能会将派生类实例与其基类实例视为等同。这样可能会导致一些意想不到的结果。为了避免这种情况,可以使用getClass()方法将派生类实例与基类实例区分开来。如果两个对象的类不同,那么它们肯定不相等。
4、避免使用instanceof运算符
在某些情况下,可能会想通过使用instanceof运算符实现equals()方法。但这种方法会破坏equals()方法的对称性和传递性。如下所示:
public boolean equals(Object obj) { if (!(obj instanceof YourClass)) { return false; } YourClass yourClass = (YourClass) obj; //比较两个对象是否相等 return this.property1 == yourClass.property1 && this.property2.equals(yourClass.property2); }
在上述代码中,如果obj是YourSubClass的一个实例,那么在比较yourClass的属性时会导致ClassCastException异常。因此,尽量不要使用instanceof运算符进行类型判断。
三、使用Objects.equals()方法进行比较
Java SE 7 中添加了 Objects类,该类包含静态方法equals(),可以用来比较两个对象是否相等。引用为null的对象也被处理得非常好,因此它们不会抛出NullPointerException异常。例如:
public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final YourClass other = (YourClass) obj; if (!java.util.Objects.equals(this.property1, other.property1)) { return false; } if (!java.util.Objects.equals(this.property2, other.property2)) { return false; } return true; }
四、总结
equals()方法是Java对象比较的方法,在自定义类中,需要重写equals()方法,实现根据实际需求进行比较。在重写equals()方法时,需要遵守equals()方法的契约,并使用Objects.equals()方法进行比较。