在学习了软件构造3.5节知识后,对于java中判断相等的方法有了更深的理解。
在java中判断两个对象是否相等一般有两种方法,第一种方法便是在c语言中常见的==,而第二种是使用Object类中自带的equals方法来判断相等。总体来说,对于基本数据类型,我们使用==来判断相等(需要注意,==判断的是两个变量是否指向内存中的同一段空间),而对于对象类型,我们使用equals方法来判断相等。
在java的Object类中,可以发现equals方法是这样实现的:
public class Object{
public boolean equals(Object that){
return this==that;
}
}
这告诉我们,Object类中实现的equals方法实际上判断的是引用等价性,即使判断两个变量是否指向同一个内存中的对象,而对于imutable类来说,由于每个imutable变量都指向了不同的对象,我们在直接引用Object类中的equals方法来判断是否相等便会出错。所以我们需要重写equals方法。
对于java中自带的类,比如Set,List等,java在定义这些类时已经为他们重写了equals方法,因此我们可以直接调用他们的equals方法来判断相等。而对于我们自己定义的类,可能需要重写equals方法。
对于自己定义的类,我们也需要分两种情况来讨论,一种是mutable类,一种是inmutable类。在此之前,我们需要明白两个概念。
一个是观察等价性,一个是行为等价性。观察等价性即是说两个类相等,只需要两个类中的某些属性表现给用户是一样的则是认为相等。而行为等价性是说两个变量指向的是同一个对象,即指向内存中的同一段空间。对于mutable类,我们只需要判断行为等价性即可,也就说直接调用Object类中的equals方法即可,无需重写equals方法。而对于inmutable类,,我们需要判断其的观察等价性。所以需要重写equals方法,否则即使两个inmutable类表现出来的属性相同,但调用Object类中的equals方法会判断为不相等。
我们还要注意的是,在重写equals方法后一定要重写hashcode方法,因为java中默认两个相等的对象一定具有相同的hashcode码,所以重写hashcode方法也是必须的。
总之,equals重写伴随着hashcode方法重写