Java自动装箱与拆箱是编译期语法糖,编译器将Integer i=10;替换为Integer.valueOf(10),int n=i;替换为i.intValue(),无运行时转换且valueOf有缓存优化。

Java 自动装箱与拆箱本质是编译器在编译阶段插入的“语法糖”,不改变运行时行为,但极大简化了代码书写。它不是运行时的动态转换,而是在 javac 编译期 就被替换成明确的方法调用。
自动装箱:编译器调用 valueOf() 替换赋值
当你写 Integer i = 10;,编译器不会保留这个“直接赋值”的字节码,而是立即重写为:
- 识别右侧是
int常量,左侧是Integer引用类型 → 触发装箱 - 插入
Integer.valueOf(10)调用(不是new Integer(10)) -
valueOf()方法内部有缓存优化:对 -128 到 127 的整数返回常量池中复用对象
自动拆箱:编译器调用 xxxValue() 替换取值
当你写 int n = i;(其中 i 是 Integer),编译器会将其转为:
- 识别左侧是基本类型
int,右侧是包装类引用 → 触发拆箱 - 插入
i.intValue()调用 - 若
i为null,运行时抛出NullPointerException(因为null.intValue()非法)
反编译可验证:字节码里没有“自动”二字
用 javap -c 查看编译后的 class 文件,你会发现:
立即学习“Java免费学习笔记(深入)”;
-
Integer i = 42;对应字节码含invokestatic java/lang/Integer.valueOf(I)Ljava/lang/Integer; -
int x = i;对应字节码含invokevirtual java/lang/Integer.intValue()I - 没有任何特殊指令或运行时机制参与——纯编译期替换
为什么不用 new?valueOf() 更高效
编译器坚持用 valueOf() 而非构造器,是因为:
-
new Integer(5)每次都新建对象,浪费内存(JDK 9+ 已标记为过时) -
Integer.valueOf(5)可复用缓存对象,减少 GC 压力 - 所有包装类的
valueOf()都遵循类似策略(Boolean全缓存,Character缓存 0–127 等)


















