int 與 Integer 是 Java 開發中最高頻的基本類型與包裝類型組合。看似簡單,實則蘊含記憶體模型、自動拆裝箱、快取機制、泛型擦除等核心知識點。本文將從底層實現、語義差異、效能陷阱、最佳實踐四個維度徹底講透。
| 特性 | int (基本類型) | Integer (包裝類型) |
|---|---|---|
| 分類 | Primitive Type (原始類型) | Reference Type (引用類型) |
| 預設值 | 0 | null |
| 記憶體儲存 | 堆疊區直接儲存數值 | 堆區儲存物件,堆疊存引用 |
| 方法支援 | 無(非物件) | 豐富(parseInt、toString、compareTo 等) |
| 泛型支援 | 不支援 | 支援(List<Integer>) |
| 序列化 | 需包裝 | 實現 Serializable |
// Web 表單場景
class ExamForm {
// int score = 0; // 無法區分「缺考」與「考了 0 分」
Integer score; // null = 缺考,0 = 考了 0 分
}
JSP/EL 表達式中:${form.score} → int 顯示 0,Integer 顯示空白,體驗更佳。
// 推薦:Integer OID
@Entity class User {
@Id @GeneratedValue
private Integer id; // null = 臨時對象,自動判斷
}
// 不推薦:int OID 需額外配置
@Entity class User {
@Id @GeneratedValue
private int id; // 需在 hbm.xml 配置 unsaved-value="0"
}
Integer a = 100; // 自動裝箱 → Integer.valueOf(100)
int b = a; // 自動拆箱 → a.intValue()
a++; // 拆箱 → 運算 → 裝箱
// JDK 內部實現
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(新建物件,比較引用)
// 正確比較方式
System.out.println(c.equals(d)); // true
// 反例:長循環產生海量 Integer 物件
Long sum = 0L; // 錯誤用 Long 包裝類
for (long i = 0; i < 1_000_000; i++) {
sum += i; // 每次拆箱+加法+裝箱,產生 100 萬 Long 物件
}
// 正例:使用基本類型累加
long sum = 0L;
for (long i = 0; i < 1_000_000; i++) {
sum += i; // 零物件分配
}
| 基本類型 | 包裝類型 | 快取範圍 |
|---|---|---|
| boolean | Boolean | TRUE/FALSE 兩個單例 |
| byte | Byte | -128 ~ 127 全快取 |
| char | Character | 0 ~ 127 |
| short | Short | -128 ~ 127 |
| int | Integer | -128 ~ 127 |
| long | Long | -128 ~ 127 |
| float | Float | 無快取 |
| double | Double | 無快取 |
List<Integer>).equals(),除非確定在快取範圍內理解 int 與 Integer 的本質差異,是寫出高效、正確、可維護 Java 代碼的基礎功力。