int与Integer的自动装箱拆箱是编译期语法糖:装箱即插入Integer.valueOf(),拆箱即插入intValue();缓存范围-128~127影响==结果,但应避免用==比较包装类。

理解 int 与 Integer 的隐式自动装箱与拆箱,关键在于认清:这不是 JVM 运行时的“智能判断”,而是 javac 编译器在编译期**硬编码插入方法调用**的语法糖。
装箱本质是编译器塞进 Integer.valueOf()
当你写 Integer i = 100; 或 list.add(42);,编译器会直接替换成:
- Integer i = Integer.valueOf(100);
- list.add(Integer.valueOf(42));
反编译字节码(如用 javap -c)能看到明明白白的 invokestatic java/lang/Integer.valueOf 指令。它和你手写 valueOf() 完全等价,只是省了几个字符。
拆箱本质是编译器塞进 intValue()
当你写 int x = i;、if (i == 5) 或 i + 1,编译器会转成:
- int x = i.intValue();
- if (i.intValue() == 5)
- i.intValue() + 1
只要 i 是 null,这一行就立刻抛 NullPointerException——不是运行中“某处”出错,而是拆箱动作本身执行失败。
缓存机制只影响 valueOf() 返回的对象身份
Integer.valueOf(int) 对 -128 到 127 范围内的值返回缓存对象,超出则新建实例。这带来两个典型现象:
- Integer a = 100, b = 100; → a == b 为 true(同一缓存对象)
- Integer c = 200, d = 200; → c == d 为 false(各自新建)
但要注意:这是 valueOf() 的实现细节,不是语言规范保证的行为;用 == 比较包装类永远不可靠,应改用 Objects.equals(a, b) 或显式判空后取值。
哪些场景会静默触发?三类上下文最常见
编译器只在类型契约被打破、必须补全转换的地方才插代码,主要包括:
- 赋值:int → Integer(装箱),Integer → int(拆箱)
- 方法调用:传 int 给接收 Integer 的参数(装箱),传 Integer 给接收 int 的参数(拆箱)
- 表达式运算与比较:如 a + b(若 a 是 Integer,b 是 int)、a == 5、a ? b : c 都会触发拆箱
泛型擦除也在此列:ArrayList<Integer> 实际存 Object,所以 add(1) 必须装箱,get(0) 后赋给 int 必须拆箱。

















