Java包装类缓存机制的核心是通过预创建并复用常用值对象(如Integer默认-128~127)来减少内存占用、降低GC压力、提升性能;仅Byte、Short、Long、Integer、Character和Boolean支持缓存,其中Integer范围可调,Float/Double无缓存。

Java 基本类型没有对象行为,而包装类让它们能参与面向对象体系——缓存池是其中关键优化设计,核心目标是减少重复对象创建、节省内存、提升性能。
缓存池存在的根本原因
程序中大量使用小整数(如循环变量、状态码、索引)、ASCII字符、布尔值等。若每次 new Integer(5) 都新建对象,会快速堆积大量内容相同、生命周期短的对象,加重 GC 压力。缓存池在类加载时就预创建一批常用值的实例,后续复用即可。
- 所有缓存对象在类初始化阶段一次性生成,存于方法区(JDK 8+ 的元空间),线程共享
- 缓存范围固定且较小(如 -128 ~ 127),保证初始化开销可控
- 浮点型(
Float/Double)不设缓存:因数值连续、精度敏感,缓存无意义且易引发歧义
Integer 缓存机制的典型实现逻辑
Integer.valueOf(int i) 是触发缓存的入口,其判断逻辑直接对应缓存边界:
- 检查
i是否落在IntegerCache.low(默认 -128)与IntegerCache.high(默认 127)之间 - 是 → 返回
IntegerCache.cache[i + 128](通过偏移量定位数组元素) - 否 → 调用
new Integer(i)创建新对象
注意:new Integer(100) 总是新建对象,绕过缓存;而 Integer.valueOf(100) 或自动装箱 Integer i = 100; 会命中缓存。
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
立即学习“Java免费学习笔记(深入)”;
哪些包装类有缓存?范围是否可调?
支持缓存的仅限离散、高频、取值集有限的类型:
- Byte / Short / Long:固定缓存 -128 ~ 127,不可配置
-
Integer:默认 -128 ~ 127,可通过 JVM 参数扩展上限:
-Djava.lang.Integer.IntegerCache.high=500 - Character:缓存 0 ~ 127(即 ASCII 可见字符和控制字符)
-
Boolean:仅两个实例
Boolean.TRUE和Boolean.FALSE,本质是静态常量 - Float / Double:无缓存机制
缓存带来的实际影响与注意事项
最典型的陷阱是用 == 比较包装类引用:
Integer a = 127; Integer b = 127; System.out.println(a == b); // true(同对象)Integer c = 128; Integer d = 128; System.out.println(c == d); // false(不同对象)- 正确做法始终是用
.equals()比较值,或用int基本类型做运算 - 缓存行为只对
valueOf()和自动装箱生效,new构造器永远不走缓存

















