深入探究"=="與equals方法的區別

一、常見的回答:

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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章