踩坑筆記之Integer數值比較

很多東西,表面上看起來挺簡單,實際上別有洞天,一不小心就是一個坑。記錄一下昨天遇到的Integer數值比較所遇到的“奇葩BUG”。

1.問題場景

先看如下一段代碼

if(activity.getTotalCounts()==activity.getParticipationCounts())  {
    long time = activity.getUpdatedAt().getTime()+60*30*1000;
    vo.setProbableOpenTime(new Date(time));
 }

activity.getTotalCounts() 和activity.getParticipationCounts()的值都是Integer類型,在兩者數值都一樣的時候,測試發現vo.setProbableOpenTime(new Date(time)); 這段代碼竟然有時候能執行到,有時候卻不行。比如 都等於100時,能夠執行到這段代碼,都等於200時卻不行了,好奇怪的問題,都是一樣的數值怎麼就有時候成立,有時候不成立呢!於是有了下面這段測試代碼

2.Integer數值比較單元測試

    @Test
    public void IntegerTest() {

        Integer a = 100;
        Integer b = 100;
        Integer c = 300;
        Integer d = 300;
        System.out.println(a==b);
        System.out.println(c==d);
        System.out.println(c.equals(d));
    }

輸出結果爲:
true
false
true
結果可知,Integer 用==比較數值確實有時候成立,有時候卻不行。

3.問題的本質
想知道爲啥有這麼奇怪的結果,還是要看看源代碼的,如下:

     * This method will always cache values in the range -128 to 127,
     * inclusive, and may cache other values outside of this range.
   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);
    }

Integer a = 100實際上調用了valueOf(int i)方法。
這裏low是-128,high是127,從方法的註釋中可以得知,在[-128,127]之間,Integer總是緩存了相應數值對象,這樣每次取值時都是同一個對象,而不在此區間時,則不一定會緩存,那麼取出兩個同樣數值大小的對象則不是同一個對象,每次都會new Integer(i);,所以其對象的地址不同,則用==比較是自然不會成立。Integer緩存的目的正如註釋所言better space and time performance by caching frequently requested values.但是個人以爲這樣的設計又何嘗不是雷區!

爲了防止不小心掉入這樣的陷阱,對於基本類型的比較,用“==”;而對於基本類型的封裝類型和其他對象,應該調用public boolean equals(Object obj)方法(複雜對象需要自己實現equals方法)。

昨天解決完問題,突然靈光一現,我嚓,這是多有趣的一道面試題啊,下次面試別人時,我得問問,哈哈!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章