IntegerCache的妙用和陷阱!

  • 2020 年 9 月 29 日
  • 筆記

考慮下面的小程式,你認為會輸出為什麼結果?

public class Test {

    public static void main(String\[\] args) {

        Integer n1 = 123;

        Integer n2 = 123;

        Integer n3 = 128;

        Integer n4 = 128;

        System.out.println(n1 == n2);

        System.out.println(n3 == n4);

    }

}

答案如下:

true

false

是否和你預想的一致?

我們知道==比較的是對象的引用,那這裡為什麼會這出這種情況呢?

原理

首先這是JDK在1.5版本中添加的一項新特性,把-128~127的數字快取起來了,用於提升性能和節省記憶體。所以這個範圍內的自動裝箱(相當於調用valueOf(int i)方法)的數字都會從快取中獲取,返回同一個數字,所以現在你理解為什麼了吧。同時這也會給我們開發帶來預想不到的陷阱,直得注意!!

而我們通過new Integer(1)這樣就不會從快取中獲取,大家可以自行測試。

我們來翻看下jdk中Integer的源碼

上面是IntegerCache的源碼,把從-128~high放在快取中

上面是valueOf的源碼,先從快取中獲取,獲取不到再new一個返回

從源碼裡面我們可以看到最小邊界是-128,最大邊界可以通過-XX:AutoBoxCacheMax進行配置,但也不會大於Integer.MAX_VALUE最大值。

擴展

這種快取行為不僅用於Integer類,而且還用於Long,Short,Byte,Character,大家可以去這些類裡面查看XxxCache的類和valueOf方法源碼,原理大致相同,但它們的邊界略有一二,也不能進行最大邊界的配置。

近期熱文推薦:

1.Java 15 正式發布, 14 個新特性,刷新你的認知!!

2.終於靠開源項目弄到 IntelliJ IDEA 激活碼了,真香!

3.我用 Java 8 寫了一段邏輯,同事直呼看不懂,你試試看。。

4.吊打 Tomcat ,Undertow 性能很炸!!

5.《Java開發手冊(嵩山版)》最新發布,速速下載!

覺得不錯,別忘了隨手點贊+轉發哦!