一、常見的回答:
equals比較的是對象的內容,而" =="比較的是對象的地址。
二、較爲完整的回答
“默認情況下, 也就是從Object類中集成而來的equals方法與 == 是完全”等價的,也就是比較的是對象在內存中的地址。但是我們可以重寫equals方法, 使其按照我們需要的方式進行比較,例如String類重寫了equals方法,時其比較的時字符序列,而不再是內存地址。”
三、下面我們通過幾個例子來深入探究"=="與equals方法
1、我們創建一個Person類,然後創建並實例化兩個對象分別爲personOne 、PersonTwo 。
‘=='運算符比較兩個Person對象(personOne 與PersonTwo ),返回false, 這個是在意料之中的,因爲personOne 與PersonTwo 是兩個不同的對象, 因而地址也不會相同。程序的原意是,如果兩個人的名字(name) 相等,就認爲是同一個人,否則不是同一個人。然而, 儘管personOne 與PersonTwo 兩個對象的名字相同,但是結果卻事與願違,equals 方法同樣返回了false。
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public static void main(String[] args) {
Person personOne = new Person("Jennifer");
Person PersonTwo = new Person("Jennifer");
System.out.println(personOne == PersonTwo); //false
System.out.println(personOne.equals(PersonTwo)); //false
System.out.println(personOne.hashCode()); //366712642
System.out.println(PersonTwo.hashCode()); //1829164700
}
}
2、下面我們再來看一個String、StringBuffer 、StringBuilder 的例子。
public class SttringTest {
public static void main(String[] args) {
String strOne = new String("");
String strTwo = new String("");
System.out.println(strOne == strTwo); //false
System.out.println( strOne.equals(strTwo)); //true
StringBuffer bufferOne = new StringBuffer();
StringBuffer bufferTwo = new StringBuffer();
System.out.println(bufferOne == bufferTwo); //false
System.out.println(bufferOne.equals(bufferTwo)); //false
StringBuilder buliderOne = new StringBuilder();
StringBuilder buliderTwo = new StringBuilder();
System.out.println(buliderOne == buliderTwo); //false
System.out.println( buliderOne.equals(buliderTwo)); //false
}
}
3、如果對於這樣的結果我們不明白爲什麼,那就是我們沒有弄清楚equals方法到底比較的是什麼。下面我們來看看String、StringBuffer 、StringBuilder中equals方法的源碼:
4、 String中equals方法的源碼
5、 StringBuffer 、StringBuilde中equals方法的源碼
四、 問題總結:
從其根源來看,equals方法是在Object類中聲明的,訪問修飾符爲public,而所有類(除Object類自 身外)都是Object的直接或間接子類,也就是 所有子類都繼承了這個方法。在Object類中,equals方法實現如下:
public boolean equals(0bject obj) {}
從而可知, 在Object類中,equals方法與 == 運算符是完全等價的,而我們編寫的Person 類繼承了Object類中的equals方法,因此,Person 類中equals方法與 == 是等價的,也就是比較的是對象的地址,而非對象的內容。
對於String類,之所以該類可以比較對象的內容, 那是因爲String類重寫了equals方法,使該方法比較的是字符序列(也就是我們通常所說的內容)而非對象的地址。而對於StringBuilder與StringBuffer 兩個類,與Person 類相同,沒有重寫equals方法。所有不同的對象,equals方法返回值爲false。
五、 如何重寫Person中的equals方法
@Override
public boolean equals(Object obj) {
if(obj instanceof Person) {
Person person = (Person)obj;
return name == person.name;
}
return false;
}
使用instanceof 來判斷obj所指對象的類型,如果obj是Person類對象,就可以轉換爲Person對象,然後進行兩個Person對象的名字比較,相等則返回true,否則返回false。