sponsored links

為什麼說兩個 Integer 數值之間不建議使用“==”進行比較

眾所周知阿里巴巴開發手冊裡面有一條強制的規則,說的是在包裝類物件之間的值比較的時候需要使用 equals 方法,在 -128 和 127 之間的數值比較可以使用 ==,如下圖所示。具體的原因相信大家都知道,雖然規則中提到 -128 和 127 之間的數值比較可以使用 ==,但是阿粉強烈建議你還是不要這樣,包裝類統一使用 equals,特別是如果有些數值是透過 API 或者 RPC 介面過來的,一定要注意。

為什麼說兩個 Integer 數值之間不建議使用“==”進行比較

我們看看下面的程式

public class IntegerEqualTest {

    public static void main(String[] args) {

        Integer a = genA();
        //Integer a = genB();
        Integer b = 0;
        if (a == b) {
            System.out.println("a == 0");
        } else {
            System.out.println("a != 0");
        }
        System.out.println(a == b);
        System.out.println(a == 0);
    }

    private static Integer genA() {
        return new Integer(0);
    }

    private static Integer genB() {
        return 0;
    }
}

大家可以先看下上面這一段程式碼,先猜測一下執行的結果是什麼,如果再把 Integer a = genA(); 這行註釋,Integer a = genB(); 這行放開,執行的結果又是什麼。

好,1 2 3 結果如下所示

為什麼說兩個 Integer 數值之間不建議使用“==”進行比較

當我們替換註釋那一行的時候,執行結果如下

為什麼說兩個 Integer 數值之間不建議使用“==”進行比較

看到這裡其實很多小夥伴都知道是為什麼,因為 genA() 方法裡面是使用的 Integer 的構造器,構造的是一個新的物件,所以在使用 == 做對比的時候,比較的兩個物件是不一樣的。

是的,原因是這個,但是還有一點沒說清楚那就是為什麼在使用 genA() 的時候,下面的結果會不一樣。

 System.out.println(a == b);//false
 System.out.println(a == 0);//true

其實短短的幾行程式碼裡面,包含了好幾個知識點,分別是自動裝箱拆箱以及 Integer 的 -128 到 127 的數字快取。

裝箱拆箱

裝箱:自動將基本資料型別轉換為包裝器型別;

拆箱:就是自動將包裝器型別轉換為基本資料型別。

在裝箱的時候自動呼叫的是 Integer 的 valueOf(int) 方法。而在拆箱的時候自動呼叫的是 Integer 的 intValue方法。

上面的程式碼中 Integer b = 0; 會觸發自動的裝箱呼叫 Integer valueOf() 方法。而在使用 a == 0 這句的時候,會觸發自動的拆箱。然後我們看原始碼會發現有下面快取的邏輯,其中 IntegerCache.low 是 -128,IntegerCache.high 預設是 127,不過可以透過 JVM 引數進行配置。我們這裡的程式碼是 0,所以會從快取中獲取。

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

為了充分說明 Integer 的快取,我們看下下面這段程式的執行結果

Integer c1 = 128;
Integer c2 = 128;
System.out.println(c1 == c2);

在執行之前我們先自己分析一下,首先 Integer c1 = 128 和 Integer c2 = 128 按照我們上面說的,會觸發自動裝箱呼叫 valueOf 方法,透過 valueOf原始碼我們可以看到在預設的情況下 128 已經不再 Integer 的快取裡面了,所以 if 條件不滿足會透過 new Integer 構造方法建立兩個物件,所以最終的結果應該是輸出 false。

為什麼說兩個 Integer 數值之間不建議使用“==”進行比較

下面再說一下為什麼說在 -128 和 127 以內的也不建議直接使用 == 來實現比較,很顯然就跟我們上面的genA() 方法一樣,很多時候不會一下子就知道一個方法值是怎麼得到,即使是快取範圍以內,別人也有可能是透過建構函式創建出來的,這樣我們在做比較的時候很有可能就會跟預期的不一樣,從而產生事故。

特別是如果透過 RPC 介面獲得返回結果,我們可能連別人的實現方式壓根就看不到,更沒辦法提前知道了。所以我們還是老老實實的按照阿里巴巴的 Java 規範來編寫程式碼,採用equals 方法來判斷,這樣肯定沒問題。

分類: 科技
時間: 2021-10-12

相關文章

路虎攬勝極光音響無法調節音量,估計是兩個原因造成的,建議瞭解

路虎攬勝極光音響無法調節音量,估計是兩個原因造成的,建議瞭解
車輛概況:路虎攬勝極光 2020款,提車2年行駛4.1萬公里,未發生過重大交通事故. 故障描述:車輛啟動後,播放FM音訊時,無法調整音響音量. 音響無法調節音量,可能有以下幾個原因:1,音響系統功率放 ...

長安奔奔E-Star方向盤有異響,可能是這兩個原因造成的,建議牢記

長安奔奔E-Star方向盤有異響,可能是這兩個原因造成的,建議牢記
車輛概況:長安奔奔E-Star 2020款,提車1年行駛7000公里,未發生過重大交通事故. 故障描述:車輛行駛過程中,轉動方向盤時有嘎吱嘎吱的聲音. 車輛方向盤異響,可能有以下幾個原因:1,轉向十字 ...

蘋果緊急推送iOS 15.0.1,解決兩大熱門問題,強烈建議升級

蘋果緊急推送iOS 15.0.1,解決兩大熱門問題,強烈建議升級
iPhone 13釋出以來,網友們就不斷地發現了各種各樣的問題.在網友的找茬模式下,蘋果新系統的迭代速度也很快.目前iOS15.1已經推出了兩個Beta版本.其實Beta版是不建議普通使用者升級的,但 ...

寶馬X1前擋風玻璃無故開裂,可能是兩個原因造成的,建議車主瞭解

寶馬X1前擋風玻璃無故開裂,可能是兩個原因造成的,建議車主瞭解
車輛概況:寶馬X1 2018款,提車3年多行駛6.2萬公里,未發生過重大交通事故. 故障描述:車輛前擋風玻璃自然開裂,並出現一條超過10釐米的裂痕. 前擋風玻璃開裂,可能有以下幾個原因:1,前擋風玻璃 ...

寶馬4系火花塞有機油,可能是兩種原因導致的,建議車主瞭解

寶馬4系火花塞有機油,可能是兩種原因導致的,建議車主瞭解
車輛概述: 寶馬4系 2019款,提車將近2年,行駛4萬公里左右,無重大交通事故. 故障描述:車主反饋稱,在4S店更換火花塞後,其中一隻火花塞螺紋處有明顯的液態機油. 火花塞內有機油的現象,可能是以下 ...

比亞迪e2電器裝置故障,可能是兩個原因造成的,建議瞭解清楚

比亞迪e2電器裝置故障,可能是兩個原因造成的,建議瞭解清楚
車輛概況:比亞迪e2 2019款,提車1年半行駛3.1萬公里,未發生過重大交通事故. 故障描述:車輛無法正常啟動,車內電氣裝置無法正常使用. 車內電氣裝置無法使用,可能有以下幾個原因:1,車輛放置過久 ...

廣汽豐田凌尚推出兩種配置,版本之間的差異到底在哪裡

廣汽豐田凌尚推出兩種配置,版本之間的差異到底在哪裡
文/夙靳霽 TNGA構架在此次又誕生了一款全新款車型,這款車型就是廣汽豐田凌尚.此次新車以轎車的身份所定位,並且是處在了B級車和A級車的細分領域之間,屬於一款A+級的車型.目前廣汽豐田凌尚推出了兩個版 ...

對越自衛反擊戰打贏後,我軍為何又與越南打了十年兩山輪戰?

對越自衛反擊戰打贏後,我軍為何又與越南打了十年兩山輪戰?
作者:譚亦同 對越反擊自衛戰和兩山輪戰,是40餘年前在祖國西南斷斷續續持續了近十年之久的戰爭.這兩場戰爭,隨著上世紀90年代初中越兩國關係正常化及國際關係影響,雖然敵我參戰人員大部分仍在世,但是這場戰 ...

35㎡老破小爆改神作!裝下兩個書房、植物園、三分離衛生間

35㎡老破小爆改神作!裝下兩個書房、植物園、三分離衛生間
如果有選擇,誰會買一個有50年房齡的35㎡小屋呢? 但看完Somo夫婦的設計改造思路,隔著螢幕,小夢由衷發出了一聲「wow」的感嘆! 35㎡的小空間裡,夫妻二人可以擁有各自獨立的工作空間~ 開放式的餐 ...

為什麼有兩個孩子家庭的寶寶總愛欺負獨生子女的寶寶?

為什麼有兩個孩子家庭的寶寶總愛欺負獨生子女的寶寶?
前幾天晚上下班回到家,我看到諾寶貝臉上好多一道道的彩色印記. 以為是寶貝自己在家畫畫不小心弄到臉上的,因為以前用彩筆畫畫的時候出現過這種情況.我就問寶寶是畫畫弄上去的嗎?寶寶聽到我問她當時就哭了,瞬間 ...

什麼叫演技炸裂?這些人一人分飾兩角,對比分明,圈粉無數

什麼叫演技炸裂?這些人一人分飾兩角,對比分明,圈粉無數
在娛樂圈很多人只是靠強大資源的推動,一部接著一部戲,但成績慘淡,只混了臉熟,角色並沒有給人家留下深刻印象,但有的人在劇中一人分飾兩角,對比分明,讓人看著直呼過癮,這才是演技擔當! 潘粵明 潘粵明因與董 ...

iPhone13ProMax與三星S21UItra拍照對比,兩代機皇相爭,誰贏了?

iPhone13ProMax與三星S21UItra拍照對比,兩代機皇相爭,誰贏了?
近日iPhone13ProMax釋出引起了廣泛熱議,相較於上一代,今年蘋果依舊沒有提升感測器畫素,還是祖傳的1200萬鏡頭,不過蘋果增加了感測器面積,大幅提升了進光量,同時三顆鏡頭也全部支援夜景模式, ...

兩代“釣王”的對話,化紹新談鄧剛:我們沒有矛盾,他走紅很正常

兩代“釣王”的對話,化紹新談鄧剛:我們沒有矛盾,他走紅很正常
說起釣魚界的重量級人物,化紹新和鄧剛是兩個不得不被提起的大佬.北有化紹新,南有鄧剛,凡是對垂釣稍有研究的人,肯定都聽過這兩個名字. 化紹新和鄧剛,也是被釣魚人經常拿來比較的垂釣大師.很多釣友常常會為他 ...

70年代,中國影壇,兩張著名“國字臉”,北有張連文,南有達式常

70年代,中國影壇,兩張著名“國字臉”,北有張連文,南有達式常
每個時代,都有每個時代不同的審美. 比如上個世紀70年代,大眾審美可不是喜歡現在流行的下巴尖尖的"錐子臉". 而是方正又充滿正義之感的"國字臉". 尤其是男生, ...

郭蘭英:剛出生就被扔到野外,兩任丈夫都去世,91歲無兒無女

郭蘭英:剛出生就被扔到野外,兩任丈夫都去世,91歲無兒無女
'一條大河波浪寬,風吹稻花香兩岸' 這首<我的祖國>是所有中華兒女最熟悉的歌曲, 這首歌歷久彌新不斷被翻唱,宋祖英.韓紅.王麗達都曾獻唱, 但這首歌的原唱郭蘭英始終是不能被超越的存在. 出 ...

兩胖相爭取其啥?大眾攬境對比凱迪拉克XT6

兩胖相爭取其啥?大眾攬境對比凱迪拉克XT6
朋友A年初時跟我說準備買輛車,和很多人一樣,經過了半年的對比,看車,詢價之後,目標從一臺A0級別的代步車,逐漸膨脹到中大型SUV,俗話說經濟是制約人類想法的最大限制,他的限制是:裸車價格30萬以內的合 ...

民間故事:兩鄰居老吵架,日子是越過越差,教書先生髮現了端倪

民間故事:兩鄰居老吵架,日子是越過越差,教書先生髮現了端倪
話說古時候在金華縣,東邊五里外有一個五福村.村東頭住著兩戶人家,一戶人家姓馬,男主人叫馬寬仁.另一戶人家姓林,男主人叫林大海.這兩人是鄰居,以前兩人的關係還算過得去,沒啥大矛盾.有一天發生了一件事情, ...

最小時間單元大於“普朗克時間”

最小時間單元大於“普朗克時間”
物理學家在聚精會神地研究時間結構,對時間概念的理解影響了量子力學和量子哲學的進展,自然科學研究者關注時間的量子物理學含義,社會科學研究者重視時間哲學的意義.理論上的時間概念可以分為無限微小的間隔,最小 ...

不同排量的摩托車,功率和扭矩達到多少才是“正常”的呢?

不同排量的摩托車,功率和扭矩達到多少才是“正常”的呢?
不同排量的摩托車,功率和扭矩達到多少才是"正常"的呢? 有車友在後臺留言說"總是看到一些車友在說當前排量下,這點功率和馬力怎麼怎麼滴?如果在不跟國外車型相對比的前提條件下 ...