自动装箱与拆箱是编译器语法糖,装箱调用valueOf()(含缓存机制),拆箱调用xxxValue()(可能触发NPE),==比较因引用语义易失效,字节码中仅为普通方法调用。

自动装箱与拆箱是编译器层面的语法糖,JVM 本身不直接支持,整个转换过程发生在编译阶段,运行时只是普通的方法调用。
装箱的底层其实是调用 valueOf() 方法
当你写 Integer i = 100;,编译器会悄悄替换成 Integer i = Integer.valueOf(100);。这个方法不是简单地 new 一个对象,而是先查缓存:如果数值在 -128 到 127 范围内(默认),就从 IntegerCache.cache 数组里返回已有对象;超出范围则新建实例。
- valueOf() 是推荐方式,构造器 new Integer(100) 在 Java 9+ 已被标记为过时
- 缓存范围可通过 JVM 参数 -XX:AutoBoxCacheMax=200 扩展,但只对 Integer 生效
- Byte、Short、Character、Long 也有固定缓存(通常也是 -128~127),而 Float 和 Double 的 valueOf() 不做缓存
拆箱的底层其实是调用 xxxValue() 方法
当你写 int n = i;,编译器实际生成的是 int n = i.intValue();。这一步看似简单,但隐含风险:如果 i 是 null,运行时就会抛出 NullPointerException。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 每种包装类都有对应的拆箱方法:比如 intValue()、longValue()、booleanValue() 等
- 拆箱操作不会触发缓存逻辑,它只是读取包装类内部的 final 字段(如 Integer.value)
- 在循环或高频计算场景中反复拆箱,可能因频繁调用方法和潜在的对象创建带来性能开销
== 比较失效的本质是对象引用 vs 值比较
因为装箱返回的是对象引用,所以用 == 比较两个 Integer 变量,实际比的是内存地址,不是数值大小。
立即学习“Java免费学习笔记(深入)”;
- Integer a = 127, b = 127; → a == b 为 true(共用缓存对象)
- Integer c = 128, d = 128; → c == d 为 false(各自 new 出不同对象)
- Integer e = null; 后执行 if (e == 0) → 先拆箱再比较,直接报空指针
字节码里能清楚看到编译器干了什么
用 javap -c 查看编译后的字节码,你会看到:
- 装箱对应 invokestatic Integer.valueOf
- 拆箱对应 invokevirtual Integer.intValue
- 没有特殊指令,全是标准方法调用 —— 这说明它真就是“糖”,不是 JVM 新特性

















