當(dāng)我們看到這個(gè)面試題的時(shí)候,相信大多數(shù)同學(xué)腦海中浮現(xiàn)的肯定是 == 比較的是引用,equals比較的是值,但是真實(shí)情況,equal是簡(jiǎn)單的比較值嗎?下面我們通過看下equals的源碼來(lái)分析一下:
Equals源碼分析
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
首先在代碼剛開始的位置使用了==,這代碼如果兩個(gè)對(duì)象的引用地址地址是相同的,那么默認(rèn)對(duì)象的值也是相等的。
后面判斷如果傳入的是String 對(duì)象,那么就對(duì)String對(duì)象中的每個(gè)char進(jìn)行元素比較,如果全相等,那兩個(gè)對(duì)象就相等。
為什么String的equals方法之所以比較的是值?大家有沒有明白了?
因此,String中equals的比較可以用下圖來(lái)演示:

特殊的String定義
String除了通過new的形式進(jìn)行定義,還可以通過等號(hào)賦值的形式:
String str = "10";
這是一種非常特殊的形式,不需要new就可以產(chǎn)生對(duì)象,和new有本質(zhì)的區(qū)別。
String str = "10"
String str1 = "10";
String str2 = new String("10");
System.out.println(str == str1); // return true
System.out.println(str == str2); // return false
System.out.println(str.equals(str1)); // return true
System.out.println(str.equals(str2)); // return false
要想理解上面第四行為什么==也會(huì)返回True,我們需要深入理解下JVM內(nèi)存分配管理方式

當(dāng)我們定義了一個(gè)String str = "10" , 相當(dāng)于我們定義了一個(gè)字符串常量,并沒有去New一個(gè)字符串對(duì)象,這種形式的賦值存在于常量池中,而不是像new一樣存放在堆中。當(dāng)聲明這樣一個(gè)字符串時(shí),JVM會(huì)在常量池中先查找有沒有對(duì)應(yīng)值的對(duì)象。如果有,把它賦給當(dāng)前引用,即原來(lái)的引用和現(xiàn)在的引用指向了同一對(duì)象。如果沒有,則在常量池中新創(chuàng)建一個(gè)對(duì)象,以這形式聲明的字符串,只要值相等,任何多個(gè)引用都指向同一對(duì)象,而new形式創(chuàng)建String對(duì)象是每次調(diào)用就產(chǎn)生一個(gè)新的對(duì)象。