“==”和equals

一直對Java中的“==”和equals的用法一知半解,在實(shí)際使用中又因?yàn)镃haracter、String等分裝類且伴隨toString和String.valueOf等方法的使用后則更加傻傻分不清楚,需要不斷調(diào)試才能完全搞定,因此痛定思痛,收集了一串資料終于徹底搞懂后,寫以此文,便于自身回顧,同時(shí)以饗讀者。

個(gè)人認(rèn)為《淺談Java中的equals和“==”》 這篇文章講的比較好,本文中的一些示例代碼和關(guān)鍵知識(shí)點(diǎn)也引用于該文章。

要理解關(guān)系操作符“==”和equals的區(qū)別首先要搞清楚數(shù)據(jù)變量類型,JAVA中存在基本數(shù)據(jù)類型變量和非基本數(shù)據(jù)類型變量(專業(yè)點(diǎn)的叫法是對象的引用變量),Java中有8種基本數(shù)據(jù)類型:

浮點(diǎn)型:float(4 byte), double(8 byte)

整型:byte(1 byte), short(2 byte), int(4 byte) , long(8 byte)

字符型: char(2 byte)

布爾型: boolean

需要指出的是這8種基本數(shù)據(jù)類型的變量直接存放在棧中,變量直接存儲(chǔ)的是“值”本身,而不是“地址”。因此在用關(guān)系操作符“==”來進(jìn)行比較時(shí),比較的就是 “值” (這樣設(shè)計(jì)的原因是棧有一個(gè)很重要的特性,存取速度比堆要快,存在棧中的數(shù)據(jù)可以共享,說白了就是為了提升性能)。引用類型的變量存儲(chǔ)的并不是對象的 “值”本身,而是于其關(guān)聯(lián)的對象在內(nèi)存中的地址(如圖 1)。

圖1 引用數(shù)據(jù)類型在內(nèi)存中的組織形式

看如下代碼:

public class Test1 {

public static void main(String[] args) {

int n=3;

int m=3;

System.out.println(n==m); //true

String str = new String("abc");

String str1 = new String("abc");

String str2 = new String("abc");

System.out.println(str1==str2); //false

str1 = str;

str2 = str;

System.out.println(str1==str2); // true

}

由于m和n中直接存儲(chǔ)的是值3,因此比較m==n時(shí),等價(jià)于比較3==3?顯然是相等的,返回true。而比較引用類型變量str1==str2時(shí),等價(jià)于比較對象的地址值0x001==0x333?顯然是不相等的,返回false,口語化的表示方式為str1和str2指向的是兩個(gè)不同的對象。而將str引用對象的地址值賦值給變量str1和str2后,str1和str2都指向了堆中同一對象。

我們再來看一段代碼:

public class Test1 {

public static void main(String[] args) {

System.out.println("abc"=="abc"); //true

System.out.println(new String("abc")==new String("abc")); // false

}

看了上面這段代碼,估計(jì)很多人不敢相信這樣的結(jié)果,那么就在電腦上自己敲一遍。要理解上述結(jié)果的差異,我們需要知道String是一種特殊的包裝類數(shù)據(jù)類型,它不屬于8種基本數(shù)據(jù)類型,但是我們可以像基本數(shù)據(jù)類型那樣,不通過new的方法在棧中直接創(chuàng)建String類型數(shù)據(jù),且也是共享的,意思是棧中只存在一個(gè)“abc”,因此比較的兩個(gè)“abc”實(shí)際上是同一個(gè)。

而通過new()方法創(chuàng)建的兩個(gè)String類型對象存放于堆中,雖然在棧中沒有創(chuàng)建String類型的引用變量指向他們,但是還是比較的是兩個(gè)對象的地址值。提示:只有通過new()方法才能保證每次都創(chuàng)建一個(gè)新的對象。

(二) equals方法

那如何才能判斷兩個(gè)引用類型變量所指向?qū)ο蟮膬?nèi)容是否相等呢?這時(shí)候該equals上場了。equals方法是基類Object中的方法,因此對于所有的繼承于Object的類都會(huì)有該方法。要理解equals方法的作用,看源碼是個(gè)比較好的方法。

圖2 Objects的equals方法源碼
由圖2可以看出Objects類的equals方法與關(guān)系操作符“==”其實(shí)是等價(jià)的。而String、Integer等類都對equals方法進(jìn)行了重寫,用來比較指向的對象所存儲(chǔ)的內(nèi)容是否相等。圖3是String類equals方法的具體實(shí)現(xiàn),可見equals的實(shí)現(xiàn)也是依靠關(guān)系操作符,只是將對象的內(nèi)容徹底暴露了,繞開了地址值的比較。

圖3 String類的equals方法源碼

另需注意:equals方法不能作用于基本數(shù)據(jù)類型的變量。

(三)總結(jié)

(1)對于==,如果作用于基本數(shù)據(jù)類型的變量,則直接比較其存儲(chǔ)的 “值”是否相等;如果作用于引用類型的變量,則比較的是所指向的對象的地址。

(2)對于equals方法,如果沒有對equals方法進(jìn)行重寫,則比較的是引用類型的變量所指向的對象的地址。諸如String、Date等類對equals方法進(jìn)行了重寫的話,比較的是所指向的對象的內(nèi)容。

(3)對于引用類型的變量,用“==”比較返回true的結(jié)果,那么用equals方法比較也一定返回true。



最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,460評(píng)論 6 538
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,067評(píng)論 3 423
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,467評(píng)論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,468評(píng)論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,184評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,582評(píng)論 1 325
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,616評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,794評(píng)論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,343評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,096評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,291評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,863評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,513評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,941評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,190評(píng)論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,026評(píng)論 3 396
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,253評(píng)論 2 375

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,729評(píng)論 18 399
  • 如果你沒有深度分析過的話,那么這可能是一個(gè)非常靈異的事件。 靈異事件一: 靈異事件二: 靈異事件三: 靈異事件四:...
    TinyDolphin閱讀 468評(píng)論 0 3
  • 引入 == 基本數(shù)據(jù)類型(也稱原始數(shù)據(jù)類型) :byte,short,char,int,long,float,do...
    凱諾婷閱讀 1,219評(píng)論 1 7
  • 今天是高考第一天。 比較特別的是我弟在考場。 心大的人什么都不能擊潰。但是我還是有一點(diǎn)小小的擔(dān)心和緊張。只要他認(rèn)認(rèn)...
    正山小種ww閱讀 153評(píng)論 0 0
  • 羅胖:報(bào)告 話說幾個(gè)月前,華興資本的分析師劉佳明為寫一分報(bào)告要來我們公司調(diào)研,那我就接待了一下。現(xiàn)在報(bào)告出來了,我...
    朱進(jìn)偉西農(nóng)閱讀 587評(píng)論 0 0