==:
==: 比較的是變量(棧)內(nèi)存中存放的對象的(堆)內(nèi)存地址爹殊,用來判斷兩個(gè)對象的地址是是否相同嫩舟,即是否是指的同一個(gè)對象锅纺。比較的是真正意義上的指針操作祝拯。
- 比較的是操作符兩端的操作數(shù)是否是同一個(gè)對象。
- 兩邊的操作數(shù)必須是同一類型(可以是父子類之間)才能編譯通過挑势。
- 比較的是地址冈欢,如果是具體的阿拉伯?dāng)?shù)字的比較钦椭,值想的則為true漾抬。:
int a = 10 與 long b = 10L 與 double c = 10.0 都是相同的(為true)宿亡,因?yàn)樗麄兌贾赶虻刂窞?0的堆。
equals
equals用來比較的是兩個(gè)對象的內(nèi)容是否相等纳令,由于所有的類都是繼承自java.lang.Object類的挽荠,所以用于所有的對象,如果沒有對該方法的覆蓋的話泊碑,調(diào)用的仍然是Object類中的方法坤按,而Object中的equals方法返回的卻是 == 的判斷毯欣。
String s = "abcd"是一種非常特殊的形式馒过,和new有本質(zhì)的區(qū)別。它是java中唯一不需要new就可以產(chǎn)生對象的途徑酗钞。以String s = "abcd";形式賦值在java中叫直接量腹忽,它是在常量池中而不是new一樣放在壓縮堆中。這種形式的字符串砚作,在JVM內(nèi)部發(fā)生字符串拘留窘奏,即當(dāng)生命這樣的一個(gè)字符串后,JVM會(huì)在常量池中先查找有沒有一個(gè)值為"abcd"的對象葫录,如果有着裹,就會(huì)把它賦給當(dāng)前引用,即原來那個(gè)引用和現(xiàn)在的引用指向了同一對象米同,如果沒有骇扇,則在常量池中創(chuàng)建一個(gè)新的"abcd",下一次如果有String s = "abcd";又會(huì)將s指向"abcd"這個(gè)對象摔竿,即以這個(gè)形式生命的字符串,只要值相等少孝,任何多個(gè)引用都指向同一個(gè)對象继低。
而String s = new String("hello");和其他任何對象一樣,每調(diào)用一次就產(chǎn)生一個(gè)對象稍走,只要他們調(diào)用袁翁。
可以這么理解:String str ="hello";先在內(nèi)存中找是不是有"hello"這對象,如果有婿脸,就讓str指向"hello",如果內(nèi)存里沒有"hello",就創(chuàng)建一個(gè)新的對象保存"hello";String str = new String("hello");就不管是不是已經(jīng)有"hello"這個(gè)對象粱胜,都新建一個(gè)對象保存"hello"。
具體我們看如下代碼:
public class He2 {
public static void main(String[] args) {
String a = new String("ab"); // a 為一個(gè)引用,在內(nèi)存中創(chuàng)建一個(gè)空間存儲(chǔ)"ab"對象
String b = new String("ab"); // b為另一個(gè)引用,在內(nèi)存中創(chuàng)建另一個(gè)空間存儲(chǔ)"ab"對象狐树。
String aa = "ab"; // 放在常量池中(先在常量池中尋找是否有aa這個(gè)對象年柠,如果沒有則創(chuàng)建)
String bb = "ab"; // 從常量池中查找(上面已經(jīng)創(chuàng)建了aa這個(gè)對象,所以就直接引用aa對象的地址值就可以了)
if (aa == bb) { // true
System.out.println("aa==bb");
/*
* 此時(shí)aa與bb相比較的是地址值褪迟,因?yàn)閍a與bb指向的是同一個(gè)地址值冗恨,所以aa == bb,
* 地址值相同味赃,值也相同掀抹。
*/
}
if (a == b) {// false,非同一對象a 與 b 都是開辟的新的內(nèi)存空間存儲(chǔ)值心俗,雖然值相等傲武,但地址值不同(==號 比較的是地址值)。
System.out.println("a==b");
}
if (a.equals(b)) {// true 城榛, 比較的是引用的值是否相同(equals比較的是值是否相同揪利。)
System.out.println("aEQb");
}
if (42 == 42.0) { // true
System.out.println("true");
}
}
}