public class IntegerTest {
public static void main(String[] args) {
objPoolTest();
}
public static void objPoolTest() {
Integer i1 = 40;
Integer i2 = 40;
Integer i3 = 0;
Integer i4 = new Integer(40);
Integer i5 = new Integer(40);
Integer i6 = new Integer(0);
System.out.println("i1==i2\t" + (i1 == i2));
System.out.println("i1==i2+i3\t" + (i1 == i2 + i3));
System.out.println("i4==i5\t" + (i4 == i5));
System.out.println("i4==i5+i6\t" + (i4 == i5 + i6));
}
}
輸出結果:
i1==i2 true i1==i2+i3 true i4==i5 false i4==i5+i6 true
Java 為了效能,對基本類型的包裝類實作了對象池機制。以 Integer 為例,編譯器會將 Integer i1 = 40; 轉換為 Integer i1 = Integer.valueOf(40);。
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
IntegerCache 是一個靜態內部類,在類加載時預先建立 [-128, 127] 範圍內的 Integer 實例緩存(長度 256)。
| 表達式 | 結果 | 原因 |
|---|---|---|
i1 == i2 | true | 40 在緩存範圍內,valueOf 返回同一個緩存實例,引用相同。 |
i1 == i2 + i3 | true | i2 + i3 觸發拆箱,變為 int 運算(40 + 0 = 40),再與 i1 比較時 i1 也拆箱為 int,比較的是基本類型值。 |
i4 == i5 | false | new Integer(40) 每次都在堆上建立新物件,不走緩存,引用不同。 |
i4 == i5 + i6 | true | 右側 i5 + i6 拆箱為 int 運算,左側 i4 也拆箱,比較基本類型值 40 == 40。 |
i1==i2 false i1==i2+i3 true i4==i5 false i4==i5+i6 true
因為 400 超出緩存範圍,Integer.valueOf(400) 每次都 new Integer(400),故 i1、i2 引用不同。
.equals():避免引用比較陷阱。int。-XX:AutoBoxCacheMax=size 可擴大上限(預設 127),但無法調整下限 -128。Integer 常量池是 Java 效能優化的經典案例。理解 valueOf 與 new 的差異、自動拆箱在 == 比較中的行為,是寫出正確且高效能 Java 代碼的基礎。