1、關(guān)于equals方法
equals方法是基類Object中的方法岛马,因此對(duì)于所有的繼承于Object的類都會(huì)有該方法索烹。為了更直觀地理解equals方法的作用,直接看Object類中equals方法的實(shí)現(xiàn)臭埋。該方法定義在Object類中踪央,其源碼如下:
/**
*Object.class
*/
public boolean equals(Object obj) {
return this == obj;
}
很顯然,在Object類中瓢阴,equals方法是用來(lái)比較兩個(gè)對(duì)象的引用是否相等畅蹂,即是否指向同一個(gè)對(duì)象。
2荣恐、關(guān)于字符串的比較
先看如下代碼:
public class Main {
public static void main(String[] args) {
String str1 = "abcd";//line 1
String str2 = new String(str1);// line 2
String str3 = "abcd";//line 3
String str4 = new String("abcd"); //line 4
String str5 = str1;//line 5
str5 = str5.concat("ef");//line 6
System.out.println(str1==str3);
System.out.println(str1==str2);
System.out.println(str2==str4);
System.out.println(str1==str5);
System.out.println(str1.equals(str3));
System.out.println(str1.equals(str2));
System.out.println(str2.equals(str4));
System.out.println(str1.equals(str5));
}
}
由上一篇博客Java基礎(chǔ)之String可知后四行的打印結(jié)果為:true,true,true,fasle,對(duì)于最后一個(gè)false結(jié)果比較容易理解液斜,str1的字符串內(nèi)容為“adcd”,str5的內(nèi)容為“abcdef”,兩者顯然不相同,故結(jié)果為false,而對(duì)于前三個(gè)結(jié)果叠穆,又該如何解釋呢少漆?
先看String類源碼中的equals方法:
/**
*String.class
*/
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj instanceof String) {
String s = (String) obj;
int i = value.length;
if (i == s.value.length) {
char ac[] = value;
char ac1[] = s.value;
for (int j = 0; i-- != 0; j++)
if (ac[j] != ac1[j])
return false;
return true;
}
}
return false;
}
看到這里我們應(yīng)該明白了,原來(lái)String類對(duì)equals方法進(jìn)行了覆寫(xiě)痹束,用來(lái)比較指向的字符串對(duì)象所存儲(chǔ)的字符串是否相等检疫,從String類的equals方法可知,在equals方法中先進(jìn)行引用對(duì)象的比較祷嘶,如果兩者指向的內(nèi)存空間相同屎媳,及兩者指向的為同一內(nèi)存空間夺溢,字符串內(nèi)容一定相同,直接返回true烛谊,如果兩者指向的內(nèi)存空間不同风响,在進(jìn)行字符串內(nèi)容的比較,如果內(nèi)容完全相同丹禀,直接返回true,否則返回false状勤。
3、關(guān)于其他類型
其他的一些類諸如Double双泪,Date持搜,Integer等,都對(duì)equals方法進(jìn)行了重寫(xiě)用來(lái)比較指向的對(duì)象所存儲(chǔ)的內(nèi)容是否相等焙矛。
4葫盼、關(guān)于關(guān)系操作符“==”
關(guān)于關(guān)系操作符“==”在《Java編程思想》中有這樣一句描述:
關(guān)系操作符生成的是一個(gè)boolean結(jié)果,它們計(jì)算的是操作數(shù)的值之間的關(guān)系
先看如下代碼:
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
int m=3;
int n=3;
System.out.println(m==n);
String str = new String("hello");
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1==str2);
str1 = str;
str2 = str;
System.out.println(str1==str2);
}
}
輸出結(jié)果為 true false true;
- 對(duì)于基本數(shù)據(jù)類型的變量村斟,變量直接存儲(chǔ)的是“值”贫导,因此在用關(guān)系操作符==來(lái)進(jìn)行比較時(shí),比較的就是 “值” 本身蟆盹。
- 對(duì)于引用數(shù)據(jù)類型的變量孩灯,變量存儲(chǔ)的是關(guān)聯(lián)的對(duì)象在內(nèi)存中的地址,str,str1,str2分別指向了一個(gè)String對(duì)象逾滥,此時(shí)str,str1,str2成為對(duì)象的引用峰档,變量str,str1,str2中存儲(chǔ)的是它們指向的對(duì)象在堆內(nèi)存中的地址,并不是對(duì)象的“值”本身匣距,也就是說(shuō)并不是直接存儲(chǔ)的字符串”hello”面哥。因此在用==對(duì)str1和str2進(jìn)行第一次比較時(shí),得到的結(jié)果是false毅待。因此它們分別指向的是不同的對(duì)象,也就是說(shuō)它們實(shí)際存儲(chǔ)的內(nèi)存地址不同归榕。
而在第二次比較時(shí)尸红,都讓str1和str2指向了str指向的對(duì)象,那么得到的結(jié)果毫無(wú)疑問(wèn)是true刹泄。
5外里、總結(jié)
- 對(duì)于==,如果作用于基本數(shù)據(jù)類型的變量特石,則直接比較其存儲(chǔ)的 “值”是否相等盅蝗;如果作用于引用類型的變量,則比較的是所指向的對(duì)象的地址;
- 對(duì)于equals方法姆蘸,注意:equals方法不能作用于基本數(shù)據(jù)類型的變量,如果沒(méi)有對(duì)equals方法進(jìn)行重寫(xiě)墩莫,則比較的是引用類型的變量所指向的對(duì)象的地址芙委;諸如String、Date等類對(duì)equals方法進(jìn)行了重寫(xiě)的話狂秦,比較的是所指向的對(duì)象的內(nèi)容灌侣。