Integer判斷相等彪腔,到底該用==還是equals

概述

這幾天,被幾道java基礎(chǔ)練習(xí)題中的==和equals給繞暈了进栽,所以打算把關(guān)于這塊的內(nèi)容好好總結(jié)下德挣,爭取下次再遇到類似的題目,自己不會(huì)再出錯(cuò)快毛,恩格嗅,就是這樣。

簡單了解

在Object類中唠帝,equals方法的定義是這樣的屯掖,

public boolean equals(Object obj)
{    
  return (this == obj);
}

這塊就有點(diǎn)懵了,這不還是用==來進(jìn)行比較的嗎襟衰?再往下搜了才知道贴铜,在大部分的封裝類中,都重寫了Object類的這個(gè)方法瀑晒,所以兩者還是會(huì)有區(qū)別的绍坝。總的來說苔悦,==是一個(gè)關(guān)系運(yùn)算符轩褐,如果比較的兩端都為基本類型,則判斷兩者的值是否相等,(判斷過程中還有不同基本類型的轉(zhuǎn)化间坐,這里不做討論)灾挨,如果比較的兩端都為引用類型的話,則比較兩者所指向?qū)ο蟮牡刂肥欠裣嗤袼危粚τ趀quals方法劳澄,首先,能調(diào)用這個(gè)方法肯定是一個(gè)對象蜈七,然后秒拔,如果這個(gè)對象所在的類重寫了equals方法,則按照重寫的方法進(jìn)行比較飒硅,如果沒有砂缩,則比較兩者所指向?qū)ο蟮牡刂肥欠裣嗤?/p>

自己動(dòng)手

了解了上面那么多內(nèi)容之后作谚,然后自己就寫了一個(gè)小小的測試程序,打算驗(yàn)證下庵芭,代碼如下:

1.public class Test{
2.  public static void main(String[] args) {
3.      Integer a = new Integer(200);
4.      Integer b = new Integer(200);
5.      Integer c = 200;
6.      Integer e = 200;
7.      int d = 200;
8.
9.      System.out.println("兩個(gè)new出來的對象    ==判斷"+(a==b));
10.     System.out.println("兩個(gè)new出來的對象    equal判斷"+a.equals(b));
11.     System.out.println("new出的對象和用int賦值的Integer   ==判斷"+(a==c));
12.     System.out.println("new出的對象和用int賦值的Integer   equal判斷"+(a.equals(c)));
13.     System.out.println("兩個(gè)用int賦值的Integer    ==判斷"+(c==e));
14.     System.out.println("兩個(gè)用int賦值的Integer    equal判斷"+(c.equals(e)));
15.     System.out.println("基本類型和new出的對象   ==判斷"+(d==a));
16.     System.out.println("基本類型和new出的對象   equal判斷"+(a.equals(d)));
17.     System.out.println("基本類型和自動(dòng)裝箱的對象   ==判斷"+(d==c));
18.     System.out.println("基本類型和自動(dòng)裝箱的對象   equal判斷"+(c.equals(d)));
19. }
20.}

執(zhí)行的結(jié)果如下

兩個(gè)new出來的對象    ==判斷false
兩個(gè)new出來的對象    equal判斷true
new出的對象和用int賦值的Integer   ==判斷false
new出的對象和用int賦值的Integer   equal判斷true
兩個(gè)用int賦值的Integer    ==判斷false
兩個(gè)用int賦值的Integer    equal判斷true
基本類型和new出的對象   ==判斷true
基本類型和new出的對象   equal判斷true
基本類型和自動(dòng)裝箱的對象   ==判斷true
基本類型和自動(dòng)裝箱的對象   equal判斷true

首先妹懒,第9行中,對于兩個(gè)new出來的Integer對象双吆,用==比較兩者眨唬,得到了false,這點(diǎn)應(yīng)該挺好理解的好乐,每次使用new關(guān)鍵字匾竿,都會(huì)在堆內(nèi)存中申請一塊空間,存放相應(yīng)的對象的值蔚万,然后在棧中存放這塊內(nèi)存的引用岭妖。而==運(yùn)算符比較兩者所指向?qū)ο蟮牡刂肥欠裣嗤暾埩藘蓧K空間反璃,地址肯定不相同昵慌,所以結(jié)果為false。
第10行中版扩,結(jié)果為true废离,查了下java的源碼侄泽,發(fā)現(xiàn)Integer重寫的equals方法是這樣的:

public boolean equals(Object obj) {
  if (obj instanceof Integer) {
    return value == ((Integer)obj).intValue();
  }
  return false;
}

又調(diào)用了一個(gè)intValue方法礁芦,它的實(shí)現(xiàn)是這樣的:

public int intValue()  
{  
  return value;  
}  

首先判斷傳進(jìn)來的Object類型是不是Integer類的一個(gè)實(shí)例,如果不是直接返回false悼尾;如果是則判斷兩者的成員變量value值是不是相等的(Integer類中定義的private final int value)柿扣,這塊又回到了基本類型的比較。value的值在創(chuàng)建這個(gè)對象的時(shí)候被賦值闺魏,兩個(gè)Integer對象傳遞的參數(shù)都為200未状,所以value值相等,返回true析桥。
看第11行前司草,先看下第5行。第5行中泡仗,用int給Integer賦值的那條語句埋虹,從jdk1.5開始能這么做了,因?yàn)閺倪@個(gè)版本開始娩怎,java引入了自動(dòng)裝箱搔课、自動(dòng)拆箱機(jī)制。第5行就是一個(gè)自動(dòng)裝箱的過程截亦,相當(dāng)于:
Integer c = Integer.valueOf(200);
在Integer類中爬泥,valueOf方法是這么實(shí)現(xiàn)的:

public static Integer valueOf(int i) {  
  assert IntegerCache.high >= 127;  
  if (i >= IntegerCache.low && i <= IntegerCache.high)  
    return IntegerCache.cache[i + (-IntegerCache.low)];  
  return new Integer(i);  
}  

上面這段代碼首先規(guī)定了一個(gè)范圍柬讨,默認(rèn)是-128-127之間,如果參數(shù)中的i在這個(gè)范圍之內(nèi)袍啡,則返回一個(gè)數(shù)組中的內(nèi)容踩官,如果不在這個(gè)范圍,則new一個(gè)新的Integer對象并返回境输。查看Integer類的源碼可以發(fā)現(xiàn)卖鲤,這個(gè)數(shù)組里面緩存了基本類型-128-127之間的Integer對象。但是由于第11行是與一個(gè)new出來的對象做比較畴嘶,所以==肯定返回的false蛋逾。
第12行,equals方法比較兩個(gè)對象的value值窗悯,所以為true区匣。
第13行,兩個(gè)自動(dòng)裝箱的變量蒋院,但是裝箱傳遞的值大于127亏钩,所以返回false。這這塊又試了下在-128到127之間的數(shù)欺旧,結(jié)果為true姑丑,大家可以試下。
第14行辞友,結(jié)果為true栅哀。兩個(gè)自動(dòng)裝箱的Integer對象,比較value称龙。
第15行留拾,這塊進(jìn)行比較的時(shí)候,會(huì)對Integer對象進(jìn)行自動(dòng)拆箱鲫尊,也就是調(diào)用intValue方法痴柔,方法如上。兩個(gè)基本數(shù)據(jù)類型進(jìn)行==判斷疫向,根據(jù)值比較咳蔚,所以結(jié)果為true。這塊可能有人會(huì)問搔驼,為什么不是對int類型進(jìn)行自動(dòng)裝箱處理呢谈火?其實(shí)這塊是java根據(jù)一個(gè)很明顯的道理進(jìn)行設(shè)計(jì)的:如果有人比較一個(gè)int類型的值和Integer類型的值,是想比較什么呢匙奴?肯定是值呀堆巧,所以這塊是對Integer對象進(jìn)行拆箱而不是對int類型裝箱了。
第16行這塊,首先調(diào)用equals方法的肯定是Integer對象谍肤,但是Integer類中重寫的equals方法參數(shù)是一個(gè)Object類型呀啦租,怎么能傳遞一個(gè)基本數(shù)據(jù)類型進(jìn)去呢?所以荒揣,這塊又是一個(gè)自動(dòng)裝箱的表現(xiàn)篷角,當(dāng)傳遞一個(gè)int類型給equals這個(gè)方法時(shí),java會(huì)自動(dòng)將這個(gè)值打包裝箱為Integer類系任,而Integer類的最終父類又是Object恳蹲,所以這塊參數(shù)的問題就解決了,然后就是兩個(gè)Integer對象進(jìn)行equals判斷俩滥,返回true嘉蕾。
第17行,首先d為一個(gè)基本類型int霜旧,c為一個(gè)Integer對象错忱,所以進(jìn)行==比較的時(shí)候,肯定會(huì)對Integer對象進(jìn)行拆箱處理挂据,所以結(jié)果為true以清。
第18行,同第16行崎逃。

總結(jié)

“==比較地址掷倔,equals比較值”這個(gè)還是挺靠譜的。但是對于包裝類和基本類型个绍,還要涉及它們的自動(dòng)裝箱勒葱、自動(dòng)拆箱,所以小心一點(diǎn)還是比較好的障贸,不要走到別人挖的陷阱中错森。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市篮洁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌殃姓,老刑警劉巖袁波,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蜗侈,居然都是意外死亡篷牌,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進(jìn)店門踏幻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來枷颊,“玉大人,你說我怎么就攤上這事∝裁纾” “怎么了信卡?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長题造。 經(jīng)常有香客問我傍菇,道長,這世上最難降的妖魔是什么界赔? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任丢习,我火速辦了婚禮,結(jié)果婚禮上淮悼,老公的妹妹穿的比我還像新娘咐低。我一直安慰自己,他們只是感情好袜腥,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布渊鞋。 她就那樣靜靜地躺著,像睡著了一般瞧挤。 火紅的嫁衣襯著肌膚如雪锡宋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天特恬,我揣著相機(jī)與錄音执俩,去河邊找鬼。 笑死癌刽,一個(gè)胖子當(dāng)著我的面吹牛役首,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播显拜,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼衡奥,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了远荠?” 一聲冷哼從身側(cè)響起矮固,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎譬淳,沒想到半個(gè)月后档址,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡邻梆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年守伸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片浦妄。...
    茶點(diǎn)故事閱讀 39,977評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡尼摹,死狀恐怖见芹,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蠢涝,我是刑警寧澤玄呛,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站惠赫,受9級特大地震影響把鉴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜儿咱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一庭砍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧混埠,春花似錦怠缸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至吏颖,卻和暖如春搔体,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背半醉。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工疚俱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人缩多。 一個(gè)月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓呆奕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親衬吆。 傳聞我的和親對象是個(gè)殘疾皇子梁钾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評論 2 355

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

  • java繼承與抽象 把多個(gè)共性的東西提取到一個(gè)類中,這是繼承的做法.但是,著多個(gè)共性的東西,在有些時(shí)候,方法聲明一...
    wanggs閱讀 281評論 0 0
  • 轉(zhuǎn)自:http://blog.csdn.net/jackfrued/article/details/4492194...
    王帥199207閱讀 8,529評論 3 93
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法逊抡,內(nèi)部類的語法姆泻,繼承相關(guān)的語法,異常的語法秦忿,線程的語...
    子非魚_t_閱讀 31,631評論 18 399
  • Java8張圖 11麦射、字符串不變性 12、equals()方法灯谣、hashCode()方法的區(qū)別 13、...
    Miley_MOJIE閱讀 3,707評論 0 11
  • 今日陰歷十一月二十蛔琅,天氣多云胎许。 快到年底了,好多人開始找工作,也有人換工作辜窑,那么新年新氣象钩述,如果計(jì)...
    Echo的樹洞閱讀 115評論 0 0