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

Java 自動裝箱拆箱深度陷阱解析:Integer 緩存、== 與 equals 行為差異、Long 比較陷阱

     編輯:Java 綜合教學

Java 自動裝箱拆箱深度陷阱解析:Integer 緩存、== 與 equals 行為差異、Long 比較陷阱

自動裝箱/拆箱是語法糖,但 == 與 equals() 在包裝類上的行為差異是高頻面試題與生產 Bug 源頭。通過反編譯還原本質。

反編譯還原裝箱拆箱本質

Integer a = 1;        // → Integer a = Integer.valueOf(1);  (裝箱)
Integer c = a + b;    // → a.intValue() + b.intValue() → Integer.valueOf(結果) (拆箱運算裝箱)

結論:賦值字面量調用 valueOf(),運算觸發 intValue() 拆箱後再 valueOf() 裝箱。

Integer 緩存機制 (-128 ~ 127)

Integer c = 3, d = 3;  // valueOf(3) 返回緩存對象 → c == d → true
Integer e = 321, f = 321; // valueOf(321) new Integer(321) → e == f → false

源碼驗證 IntegerCache 靜態初始化緩存區間,可通過 -Djava.lang.Integer.IntegerCache.high=... 調整上限。

六連測經典題目完整解析

Integer a = 1, b = 2, c = 3, d = 3, e = 321, f = 321;
Long g = 3L;

System.out.println(c == d);        // true  (緩存同一對象)
System.out.println(e == f);        // false (新建對象)
System.out.println(c == (a + b));  // true  (a+b 拆箱運算 → 3 → 裝箱 valueOf(3) 緩存 → c 同一對象)
System.out.println(c.equals(a+b)); // true  (equals 比較 intValue)
System.out.println(g == (a + b));  // true  (g 拆箱 long,a+b 拆箱 int → int 提升 long 比較)
System.out.println(g.equals(a+b)); // false (Long.equals 要求參數 instanceof Long,Integer 不符合)
美文美圖

核心規律總結表

表達式結果本質原因
包裝類 == 包裝類 (緩存區間)truevalueOf 返回同一緩存引用
包裝類 == 包裝類 (非緩存區間)falsenew 出不同對象
包裝類 == 算術表達式true/false算術觸發拆箱運算 → 裝箱 → 緩存判斷
包裝類.equals(算術表達式)true算術結果裝箱後 equals 比較值
不同包裝類 == (Long vs Integer)true基本類型提升比較 (long)
不同包裝類.equals(不同包裝類)falseequals 先判 instanceof 本類型

源碼級 equals 實現差異

// Integer.equals
public boolean equals(Object obj) {
    return obj instanceof Integer && value == ((Integer)obj).intValue();
}

// Long.equals
public boolean equals(Object obj) {
    return obj instanceof Long && value == ((Long)obj).longValue();
}

鐵律:equals 嚴格要求同類型,跨類型直接返回 false,不進行數值轉換。

生產代碼防坑指南

  1. 比較數值一律用 equals(),或拆箱為基本類型用 ==
  2. 避免包裝類作為 Map Key 進行 == 判斷
  3. 慎用自動裝箱參與運算,大量循環中產生大量臨時對象導致 GC 壓力
  4. 基本類型優先:局部變量、高頻計算優先 int/long,邊界交互再裝箱

💡 阿里巴巴開發手冊:【強制】所有的包裝類對象之間值的比較,全部使用 equals() 方法比較。

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