一、概述
在Java中,equals()方法和==是我们经常使用的,也是在面试中的常考题之一了。本篇文章就来分析一下它们二者之间的区别。
二、关于“==”
== 的比较可分为如下两种:
- 基本数据类型的比较
- 引用数据类型的比较
1. 基本数据类型的比较
使用"=="进行基本数据类型的比较时,比较的是它们的值,例如int型变量和int型变量的比较,boolean变量和boolean变量的比较都属于值之间的比较。这些都是我们平常经常使用的,这里就不给出示例了。
2.引用数据类型的比较
如果比较的对象为引用数据类型的话,比较的是它们的内存地址。此时“==”符号用于判断等号两边引用的是否为同一个对象,例子如下所示:
public class Main {
public static void main(String[] args) {
Object a = new Object();
Object b = new Object();
System.out.println(a == b);
}
}
结果:
false
由于 a、b 引用的是堆上的不同对象,所以它们用“==”判断的返回值为false,即不是同一个对象。
三、equals()方法
equals()
方法位于Object
类中,是每个类都会存在的方法,它的默认实现代码如下:
public boolean equals(Object o) {
return this == o;
}
从它内部的实现我们也可以看出,默认情况下它和“==”一样,也是比较两个对象的内存地址。但是这和我们平常对下面代码的认知有出入:
public class Main {
public static void main(String[] args) {
String a = "abc";
String b = "abc";
System.out.println(a.equals(b));
}
}
这段代码根据我们平常的使用经验来看会返回true,事实上它确实也会返回true,甚至于我们还会经常使用这样子的方式来判断字符串是否为空的情况。那么我们就来看到String中的equals()方法的实现是什么样子的:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = length();
if (n == anotherString.length()) {
int i = 0;
while (n-- != 0) {
if (charAt(i) != anotherString.charAt(i))
return false;
i++;
}
return true;
}
}
return false;
}
从上面代码中我们可以发现,String其实是重写了equals()方法,当判断不是同一个对象的时候,equals方法接下来还会对它们的值进行比较,如果完全相等的话也会返回true,所以String中的equals()方法重写过后就功能就相当于是进行了值比较,这和我们平常的使用习惯也是相符合的。
从这里我们也可以得知,在我们定义一个类时,如果我们需要比较该类型的两个对象的值是否相等,我们就需要重写equals()方法,并自定义相等的条件和规则,从而达到值比较的效果。
四、题外话之hashCode()
之所以要在这里说一下hasCode()方法是因为它和equals()方法息息相关。hashCode()方法用于计算一个对象的散列值,其中散列值是一个32bit的整数。
Java中约定:每一种数据类型的hashCode()方法都必须与equals()方法一致。也就是说,a.equals(b)返回true,那么a.hashCode()的返回值必然和b.hashCode()的返回值相同。相反,如果两个对象的hashCode()方法的返回值不同,那么我们就知道这两个对象是不同的。但如果两个对象的hashCode()方法的返回值相同,这两个对象也有可能不同,我们还需要使用equals方法进行判断。
上面的约定说明:如果我们需要为自定义的类重写hashCode()方法,那么我们需要同时重写equals()方法。默认的hashCode()会返回对象的内存地址,但这只适用于少数情况。Java为许多常用数据类型重写了该方法(String、Integer、Double、File 和 URL 等)。
希望这篇文章对您有所帮助~