避免自动装箱性能陷阱的关键是将隐式装箱转为显式可控决策:热路径禁用Integer等包装类,循环累加用基本类型;集合改用原始类型库;日志用占位符;API设计优先基本类型与OptionalInt。

避免自动装箱带来的性能陷阱,关键不是禁用它,而是把装箱行为从“看不见的编译器操作”变成“可感知、可控制的显式决策”。高频、批量、热路径上的隐式装箱最容易引发对象爆炸和GC抖动,必须主动拦截。
循环和累加场景:一律用基本类型
循环变量、计数器、累加和、索引、临时计算值——只要不涉及 null 语义或泛型约束,就该用 int、long、boolean 等原始类型。
- 写
for (int i = 0; i < n; i++),别写for (Integer i = 0; i < n; i++) - 写
int sum = 0;,再sum += arr[i];,别用Integer sum = 0; - 集合遍历时若需计算,优先
list.stream().mapToInt(Integer::intValue).sum(),而非list.stream().mapToInt(i -> i).sum()(后者仍触发拆箱)
集合操作:绕过泛型装箱瓶颈
List<Integer> 是装箱重灾区。每次 add、get、遍历都在堆上创建/访问对象,百万级数据下 GC 压力陡增。
- 数值密集场景改用原始类型集合库:Eclipse Collections 的
IntList、Trove 的TIntArrayList或 Java 21+ 的SequencedCollection<Integer>配合原始类型优化(需配合 JVM 支持) - 避免
Arrays.asList(1, 2, 3)这类写法——它直接返回已装箱完毕的List<Integer> - Android 开发可用
SparseArray<String>替代HashMap<Integer, String>,键为 int,零装箱
日志与字符串拼接:剥离装箱逻辑
看似无害的 "id=" + id + ", flag=" + flag,背后是 Integer.valueOf(id) 和 Boolean.toString(),可能伴随 new char[],高频调用时开销显著。
- SLF4J 日志统一用占位符:
log.info("id={}, flag={}", id, flag)—— 传入 基本类型参数不会触发装箱 - Android Log 封装工具方法,内部调用
String.valueOf(int),不经过Integer - 超高频日志点可复用
StringBuilder实例,避免每次调用都 new 对象
初始化与接口设计:从源头减少包装类暴露
字段、构造参数、返回值中滥用包装类,等于在系统各层埋下装箱伏笔。
- 静态常量优先用
private static final int DEFAULT_CODE = 200;,而非Integer - 构造函数参数能用
int id就别用Integer id;若需表达“可选”,用OptionalInt或明确注释契约 - 公共 API 返回值若业务上不可能为 null,直接定义为
int getId(),比Integer getId()更安全、更轻量


















