Java自动装箱效率低下的核心是频繁转换引发对象创建、GC压力、内存翻倍和CPU开销;优化关键是关键路径切断装箱/拆箱链,优先用基本类型变量、原始类型集合库(如FastUtil),慎用缓存范围外的valueOf(),合理权衡Optional使用。

Java 中自动装箱导致效率低下的核心问题,是频繁在基本类型和包装类之间来回转换,引发对象创建、GC 压力增大、内存占用翻倍、CPU 拆箱开销累积。重构目标不是“去掉所有包装类”,而是**在关键路径上切断不必要的装箱/拆箱链条**——尤其在循环、集合操作、数学计算等高频场景。
优先用基本类型变量替代包装类变量
这是最直接、零成本的优化。只要不涉及泛型或集合,就坚决用 int、long、double 等,而非 Integer、Long、Double。
- 累加、计数、索引、状态标记等场景,一律声明为基本类型;
- 避免写
Long sum = 0L,改用long sum = 0L; - 方法参数和返回值若无需 null 表达语义(如“未设置”),优先选基本类型。
用原始类型集合库替换 ArrayList 等包装类集合
ArrayList
- 新项目首选 FastUtil:提供 IntArrayList、IntOpenHashSet、Int2ObjectMap 等,API 类似 JDK 集合,性能与内存优势明显;
- Stream 密集场景可选 Eclipse Collections,其 IntList 支持 map、filter 等函数式操作且无装箱;
- Trove 适合旧系统兼容,但已停止维护,不建议新用。
慎用缓存范围外的 Integer.valueOf() 和 Long.valueOf()
Integer.valueOf(i) 在 [-128, 127] 范围内复用缓存对象,超出则 new Integer(i),产生新对象。高频构造大整数时,这会快速堆积 GC 压力。
立即学习“Java免费学习笔记(深入)”;
- 避免在循环中调用
Integer.valueOf(someLargeNumber); - 如必须用包装类(如 Map
的 key),优先让 key 落在缓存范围内; - 对非缓存范围值,考虑是否可用 long/int 直接参与计算,再按需转包装类(且仅在必要位置)。
用 Optional 替代 null 检查时注意代价
Optional 是引用类型,本身就有对象开销。若只是做空值判断,且业务逻辑简单,用基本类型 + 特殊值(如 -1、0、-999)往往更轻量。
- 例如 ID 字段为 int,可用 -1 表示“无效ID”,比 Optional
更省内存和 CPU; - 只有当语义明确需要“存在/不存在”二元状态,且调用链天然支持 Optional(如 Stream 或 CompletableFuture)时,才选用它。


















