原文鏈接:
Java中equlas和==的區(qū)別
參考鏈接:
Object
正文
Java中的數(shù)據(jù)類型可以分為兩類:
1哺呜、基本數(shù)據(jù)類型匣砖,也稱原始數(shù)據(jù)類型。byte,short,char,int,long,float,double,boolean查描。
2痴鳄、復合數(shù)據(jù)類型(類)。
1县貌、==
在Java中术陶,當我們用"=="比較數(shù)據(jù)時,對于基本類型煤痕,我們比較的是他們的值梧宫。而對于復合數(shù)據(jù)類型,我們比較的是他們在內(nèi)存中的存放地址摆碉。
例子:
public class JavaStudyTest {
public static void main(String[] args) {
int i1 = 1;
int i2 = 1;
String str1 = new String("str");
String str2 = new String("str");
System.out.println("i1 == i2 ? " + ( i1 == i2 ));
System.out.println("str1 == str2 ? " + ( str1 == str2 ));
}
}
在上面的代碼中塘匣,我們創(chuàng)建了兩個int變量i1和i2,給它們的賦值都為1巷帝,有創(chuàng)建了兩個String對象str1和str2忌卤,字符串的內(nèi)容都為"str"。當我們用"=="比較i1和i2,str1和str2時楞泼,輸出結果如下:
可以看到驰徊,“==”判斷“i1==i2”的結果是true历谍,因為i1和i2為基本類型,所以“==”比較的是它們的值辣垒,而它們的值都為1望侈。
“==”判斷“str1==str2”的結果是false,雖然str1和str2內(nèi)容都為"str"勋桶,但是我們使用new創(chuàng)建的是兩個對象脱衙,內(nèi)存分配給他們的地址是不同的,對于非基本類型例驹,"=="比較的是他們的地址捐韩。
2、equals
Java中所有的類都是繼承于Object這個基類的鹃锈,在Object中定義了一個equals方法荤胁,源碼如下:
public boolean equals(Object obj) {
return (this == obj);
}
可以看到,在Object類中屎债,equals方法本質(zhì)用的還是"=="對數(shù)據(jù)進行比較仅政,但是在一些類庫中,equals方法被覆蓋掉了盆驹,如String,Integer,Date在這些類中圆丹,equals有其自身的實現(xiàn),而不是比較對象在堆內(nèi)存中的存放地址了躯喇。
下面我們看看關于String類的equals方法:
public class JavaStudyTest {
public static void main(String[] args) {
String str1 = new String("str");
String str2 = new String("str");
System.out.println("str1 == str2 ? " + ( str1 == str2 ));
System.out.println("str1 equals str2 ? " + ( str1.equals(str2)));
}
}
輸出結果:
可以看出辫封,String類的equals方法比較的不是String對象的存放地址了。
3廉丽、字符串緩沖池
先看一個例子:
public class JavaStudyTest {
public static void main(String[] args) {
String str1 = new String("str");
String str2 = new String("str");
String str3 = "abc";
String str4 = "abc";
System.out.println("str1 == str2 ? " + ( str1 == str2 ));
System.out.println("str1 equals str2 ? " + ( str1.equals(str2)));
System.out.println("str3 == str4 ? " + ( str3 == str4 ) );
System.out.println("str3 equals str4 ? " + (str3.equals(str4)));
}
}
再看輸出結果:
可以看到倦微,"str3==str4"結果為true,這是為什么呢正压?
程序在運行的時候欣福,會創(chuàng)建一個字符串緩沖池。當我們使用str3 = "abc"這樣的表達式來創(chuàng)建字符串時蔑匣,程序首先會在String緩沖池中尋找相同值的對象劣欢,所以,在str3 = "abc"創(chuàng)建字符串時裁良,"abc"這個字符串先被放到了緩沖池中凿将,當創(chuàng)建str4時,程序在緩沖池中尋找到了具有相同值的str3价脾,于是將str4引用指向str3所引用的"abc"對象牧抵。
而當我們使用new表達式創(chuàng)建String對象時,表明我們是需要創(chuàng)建新的對象,于是就會在堆中為我們創(chuàng)建新的String對象犀变,不會引用舊的對象妹孙。
我們再看看一個特殊的例子:
public class JavaStudyTest {
public static void main(String[] args) {
String str1 = "abc";
String str2 = new String("abc");
String str3 = str2.intern();
System.out.println("str1 == str3 ? " + ( str1 == str3 ));
}
}
再看看比較結果:
為什么結果為true呢,因為雖然String的intern方法的返回值還是字符串获枝,比如"abc".intern返回的還是字符串"abc"蠢正,但是實際上,在返回"abc"字符串時省店,它先檢查緩沖池中是否存在"abc"字符串嚣崭,如果存在,就返回池中的字符串懦傍;如果不存在雹舀,該方法就將"abc"添加到池中,再返回池中的它的引用粗俱。