解決一個問題的最好方法就是發現一個問題產生的根源,即發現最本質的東西,再去解決它。java
Java語言裏面的equals()方法是交給開發者們本身去覆蓋重寫編寫功能的,即讓開發者去定義當知足什麼條件時,兩個Object是相等的。測試
equals方法是由Object提供的,容許子類進行重寫。this
equals()的原始代碼實現以下:code
public boolean equals(Object obj) { return (this == obj); }
而有一些博客說equals()是比較具體的內容是否是相同的,這個說法其實不太準確,以偏概全。這個說法的來源是不少教程都是以String類中的equals()爲參照物進行舉例,String類的equals()重寫了Object對象的原始equals方法,只會比較具體的內容。對象
String類的equals()的具體實現代碼以下:教程
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = count; if (n == anotherString.count) { char v1[] = value; char v2[] = anotherString.value; int i = offset; int j = anotherString.offset; while (n-- != 0) { if (v1[i++] != v2[j++]) return false; } return true; } } return false; }
而 == 是比較兩個引用在內存中指向的是否是同一個對象,也就是在內存中的存儲地址是否是同樣的,兩個對象的引用相同時(指向的是同一個對象),則 == 會返回true,不然返回false。內存
因此 == 是和Object類的原始equals()方法是等價的。開發
如今不少類都對equals進行了重寫,這裏用常見的String類來編寫個測試Demo字符串
public class TestString { public static void main(String[] args) { String string_1 = "codevald"; String string_2 = "codevald"; System.out.println(string_1 == string_2); //結果爲true String string_3 = new String("codevald"); String string_4 = "code" + new String("vald"); System.out.println(string_3 == string_4); //結果爲false System.out.println(string_3.equals(string_4)); //結果爲true } }
能夠看到Demo中第一個輸出語句結果爲true博客
String string_1 = "codevald"會如今棧中建立一個對String類的引用變量string_1,而後會去字符串常量池中尋找有沒有"codevald",由於是第一次建立沒有,則會將"codevald"存放進字符串常量池。
String string_2 = "codevald" 又在棧中建立了String類的引用變量string_2,而後會去字符串常量池中尋找有沒有"codevald",若是沒有,則會建立並存放進常量池,並將string_2指向"codevald",若是已經有了,則直接令string_2指向"codevald"。上面的代碼已經將字符串存儲進了常量池,因此兩個引用(string_1和string_2)指向同一個"codevald",返回true。
String string_3 = new String("codevald")會在堆中建立一個對象,並將在棧中存在的對象引用指向堆中的對象,而String string_4則是分別用了常量池中的字符串和存放對象的堆中的字符串,作 + 的時候會進行動態調用,最後建立完生成的對象仍然存放在堆中,而兩個對象在堆中的地址是不同的,因此 == 會返回false。
而String類重寫了equals方法,比較的是內存中存放的數據的具體內容是否是相同的,這裏存放的都是"codevald",因此會返回true。
總結
對於字符串變量來講,使用""和"equals"比較字符串時,其比較方法不一樣。""比較兩個變量自己的值,即兩個對象在內存中的首地址,"equals"比較字符串包含內容是否相同。
對於非字符串變量來講,若是沒有對equals()進行重寫的話,"==" 和 "equals"方法的做用是相同的,都是用來比較對象在堆內存中的首地址,即用來比較兩個引用變量是否指向同一個對象。