Java基本类型不占堆内存、不参与GC,但误用包装类会引发高频短命对象导致OOM;应优先使用基本类型处理循环、计算、数组等场景,避免自动装箱。

Java 基本类型本身不占堆内存、不参与 GC,但一旦和包装类混用或误触发自动装箱,就容易在高频场景下批量生成短命对象,迅速拉高堆内存占用,甚至引发频繁 GC 或 OOM。避免滥用的关键,是明确“什么该用基本类型,什么不得不选包装类”,并在关键路径上主动切断装箱源头。
循环与计算场景:一律用基本类型
计数、累加、索引、状态标记、临时变量——只要不涉及 null 或泛型约束,全部使用 int、long、boolean 等基本类型。
- ❌ 错误写法:
Integer sum = 0;、for (Integer i = 0; i → 每次迭代都可能 new Integer - ✅ 正确写法:
int sum = 0;、for (int i = 0; i - 集合 add 操作也要警惕:
list.add(i)(i 是 int)会隐式调用Integer.valueOf(i),超出 -128~127 缓存范围即新建对象
集合与存储结构:优先原始类型数组或专用容器
泛型集合如 List 是装箱重灾区,每个元素都是独立对象,含对象头(12–16 字节)+ 对齐填充,内存开销可达 int[] 的 3–5 倍。
- 能用
int[]就不用List,尤其适用于数值计算、批量读取、排序、聚合等场景 - 数据库查询结果映射优先转为
int[]或long[],而非List - 后端可引入
IntArrayList、IntObjectHashMap;Android 推荐SparseArray,键直接存int,零装箱 - 禁用
Arrays.asList(1, 2, 3)——它返回的是已装箱的List
日志、字符串拼接与三元表达式:剥离装箱逻辑
看似无害的字符串拼接和条件赋值,背后常藏大量隐式装箱。
- 日志避免
"id=" + id + ", flag=" + flag,改用占位符:log.info("id={}, flag={}", id, flag)(SLF4J)或封装工具方法调用String.valueOf(id) - 三元运算慎用包装类接收:
Integer status = cond ? 200 : null→ 200 不在缓存范围内,每次执行都 new 对象 - 优先用基本类型接收:
int status = cond ? 200 : -1;若需表达“缺失”语义,显式用Optional - 检查所有
public Integer getXxx()方法,业务上不可能为 null 的,直接改为int getXxx()
类型选择与变量声明:精打细算,就近而止
不盲目用默认类型,也不让变量生命周期过长。
- 小范围整数(如状态码、年龄、HTTP 状态)优先用
byte(1 字节)或short(2 字节),而非int(4 字节) - 精度要求不高的浮点计算可用
float(4 字节)替代double(8 字节) - 变量尽量在首次使用处声明,缩短作用域,减少栈空间占用和潜在逃逸风险
- 避免把基本类型数组转成
Arrays.asList(intArray)——它返回的是List,且有装箱隐患
不复杂但容易忽略:基本类型不是“低级替代”,而是性能与内存可控性的第一道防线。从循环变量开始改起,再清理集合和日志,内存压力往往立竿见影。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











