java自动装箱调用integer.valueof()并命中-128~127缓存,超出范围则新建对象;==比较结果受缓存影响,推荐用equals();boolean全缓存,byte/short/character/long缓存[-128,127],float/double不缓存。

Java 中的自动装箱(autoboxing)和拆箱(unboxing)会隐式调用 Integer.valueOf 和 Integer.intValue(),而 Integer.valueOf 在 -128 到 127 范围内默认启用缓存机制——这是触发缓存的关键入口。
自动装箱如何调用 Integer.valueOf 并命中缓存
当你写 Integer i = 100;,编译器会将其翻译为 Integer i = Integer.valueOf(100);。此时若值在 [-128, 127] 区间内,valueOf 直接返回缓存的 Integer 对象,不会新建实例。
- 缓存对象在类加载时预先创建,存于
Integer.IntegerCache.cache数组中 - 范围可由 JVM 参数
-Djava.lang.Integer.IntegerCache.high=200扩展(仅影响上限,下限固定为 -128) - 超出缓存范围(如
Integer i = 200;)则每次调用valueOf都新建对象
用 == 比较验证缓存是否生效
缓存的存在会影响引用比较结果。同一范围内通过自动装箱得到的 Integer 变量可能指向同一个对象:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
Integer a = 100, b = 100; System.out.println(a == b); // true(命中缓存)Integer c = 200, d = 200; System.out.println(c == d); // false(未命中缓存,各自 new)- 注意:始终推荐用
equals()比较值,避免因缓存导致行为不一致
手动调用 valueOf 与自动装箱效果一致
显式写 Integer x = Integer.valueOf(50); 和自动装箱 Integer y = 50; 在字节码层面完全等价,都会走相同的缓存逻辑。
- 二者都调用同一个
valueOf(int)方法,共享同一套缓存策略 - 即使关闭自动装箱(如用
-source 1.4编译),手动调用valueOf仍可利用缓存 - 反例:
new Integer(50)绕过缓存,永远新建对象(已废弃,不推荐)
其他包装类的缓存规则对比
并非所有包装类都默认缓存,且范围不同:
-
Boolean:全部缓存(仅true/false两个实例) -
Byte、Short、Character:固定缓存 [-128, 127] -
Long:默认也缓存 [-128, 127],但可通过参数扩展(类似Integer) -
Float、Double:不缓存(浮点数语义复杂,缓存无意义)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










