int 與 Integer 是 Java 基本類型與包裝類關係的縮影,理解其區別、自動拆裝箱行為、緩存機制、泛型擦除限制,是寫出正確高效代碼的基礎。
核心區別對比
維度
int (基本類型)
Integer (包裝類)
內存佔用
4 字節 (32 位有符號)
對象頭(12-16B) + int 值 + 對齊填充 ≈ 16-24 字節
默認值
0
null
存儲位置
棧幀局部變量表 / 對象實例字段
堆內存 (對象實例)
可用於泛型
❌ 不可
✅ 可 (List<Integer>)
集合存儲
❌ 不可直接存入
✅ 直接存入
null 語義
無
表示「無值」/「未初始化」
方法調用
無
parseInt、toString、compareTo、bitCount 等豐富 API
== 比較
值比較
引用比較 (需用 equals 比值)
自動拆裝箱 (JDK 5+)
// 裝箱:int → Integer
Integer i1 = 100; // 編譯器插入 Integer.valueOf(100)
Integer i2 = Integer.valueOf(100); // 顯式
// 拆箱:Integer → int
int n = i1; // 編譯器插入 i1.intValue()
int sum = i1 + i2; // 算術運算自動拆箱
// 陷阱:NullPointerException
Integer i3 = null;
int n2 = i3; // 運行時拋 NPE (拆箱調用 null.intValue())
Integer 緩存機制 (核心面試點)
// Integer.valueOf 源碼邏輯 (JDK 8+)
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
// 默認緩存範圍:-128 到 127
// 可通過 -XX:AutoBoxCacheMax=size 擴大上限 (不可調整下限)
緩存影響實例
Integer a = 100, b = 100;
System.out.println(a == b); // true (緩存命中,同一對象)
Integer c = 200, d = 200;
System.out.println(c == d); // false (超出緩存,新建對象)
Integer e = 100;
Integer f = Integer.valueOf(100);
System.out.println(e == f); // true (均走 valueOf)
Integer g = new Integer(100); // 強制新建 (JDK 9+ 棄用)
System.out.println(a == g); // false
其他包裝類緩存範圍
類型
緩存範圍
配置參數
Integer
-128 ~ 127
-XX:AutoBoxCacheMax
Short
-128 ~ 127
固定
Byte
-128 ~ 127 (全範圍)
固定
Long
-128 ~ 127
-XX:AutoBoxCacheMax
Character
0 ~ 127
固定
Boolean
TRUE/FALSE 兩個單例
固定
Float/Double
無緩存
無
集合與泛型場景
List list1 = new ArrayList<>(); // ❌ 編譯錯誤:基本類型不能作為類型參數
List list2 = new ArrayList<>(); // ✅ 正確
// 自動裝箱存入
list2.add(100); // list2.add(Integer.valueOf(100))
// 取出自動拆箱
int first = list2.get(0); // list2.get(0).intValue()
// 流式處理 (基本類型流避免拆裝箱)
IntStream intStream = list2.stream().mapToInt(Integer::intValue);
int sum = intStream.sum();
// ❌ 每次循環拆裝箱
Integer sum = 0;
for (int i = 0; i < 10000; i++) sum += i;
// ✅ 基本類型累加,最後裝箱
int sum = 0;
for (int i = 0; i < 10000; i++) sum += i;
Integer result = sum;