首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java int 與 Integer 區別深度解析:基本類型、包裝類、自動拆裝箱與緩存機制

     編輯:Java 程式設計入門

int 與 Integer 是 Java 基本類型與包裝類關係的縮影,理解其區別、自動拆裝箱行為、緩存機制、泛型擦除限制,是寫出正確高效代碼的基礎。

核心區別對比

自動拆裝箱 (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

其他包裝類緩存範圍

維度int (基本類型)Integer (包裝類)
內存佔用4 字節 (32 位有符號)對象頭(12-16B) + int 值 + 對齊填充 ≈ 16-24 字節
默認值0null
存儲位置棧幀局部變量表 / 對象實例字段堆內存 (對象實例)
可用於泛型❌ 不可✅ 可 (List<Integer>)
集合存儲❌ 不可直接存入✅ 直接存入
null 語義無表示「無值」/「未初始化」
方法調用無parseInt、toString、compareTo、bitCount 等豐富 API
== 比較值比較引用比較 (需用 equals 比值)

集合與泛型場景


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();

性能與最佳實踐

  1. 優先使用基本類型:局部變量、計算密集型、大數組 (int[] 比 Integer[] 節省 50%+ 內存)
  2. 集合/泛型/需 null 語義:使用包裝類
  3. 避免循環中拆裝箱:
    
    // ❌ 每次循環拆裝箱
    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;
    
  4. 比較用 equals:Objects.equals(a, b) (null 安全)
  5. JDK 9+ 棄用構造器:new Integer(100) → Integer.valueOf(100)

原文代碼修正版


ArrayList al = new ArrayList<>(); // 泛型化
int n = 40;
Integer nI = Integer.valueOf(n); // 使用 valueOf 而非 new
// al.add(n);      // ❌ 編譯錯誤:int 不能加入 List? 實際可裝箱加入
al.add(n);         // ✅ JDK 5+ 自動裝箱為 Integer
al.add(nI);        // ✅ 顯式包裝類

註:List 可接受 int (自動裝箱為 Integer),但 List 語法非法。

總結

int 是高效值類型,Integer 是功能豐富的對象包裝。**自動拆裝箱是語法糖,非零成本**。緩存機制導致 == 行為在 [-128,127] 內與外不一致,**永遠用 equals 比較值**。集合泛型強制使用包裝類,高性能場景用基本類型流 (IntStream) 或第三方庫 (FastUtil、Eclipse Collections) 避免裝箱開銷。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved

類型緩存範圍配置參數
Integer-128 ~ 127-XX:AutoBoxCacheMax
Short-128 ~ 127固定
Byte-128 ~ 127 (全範圍)固定
Long-128 ~ 127-XX:AutoBoxCacheMax
Character0 ~ 127固定
BooleanTRUE/FALSE 兩個單例固定
Float/Double無緩存無