如何准确区分 Integer.valueOf() 与 new Integer() 在对象创建与缓存池利用上的具体差异?
- 内容介绍
- 相关推荐
本文共计602个文字,预计阅读时间需要3分钟。
Integer.valueOf(int) 是静态工厂方法,内部根据输入值决定是否复用已有对象;new Integer(int) 是构造器调用,每次执行都会在堆上分配新内存并初始化新实例。
这意味着哪怕连续写十次 new Integer(42),也会产生十个彼此不等(== 为 false)的独立对象;而十次 Integer.valueOf(42) 在默认配置下只生成一个对象,其余九次返回同一引用。
缓存池只对 valueOf() 生效
Java 规范强制要求 Integer 类内置缓存区间:-128 到 127(含)。这个缓存由 IntegerCache 静态类维护,仅被 valueOf(int) 调用路径使用。
- 在范围内(如 100):valueOf(100) 返回缓存中固定对象,节省内存和 GC 压力
- 超出范围(如 200):valueOf(200) 仍会新建对象,但仍是通过可控的工厂逻辑,未来可优化
- new Integer(100) 或 new Integer(200):一律绕过缓存,无条件新建——缓存对其完全不可见
字符串参数时的行为差异
Integer.valueOf(String) 和 new Integer(String) 都会尝试解析字符串并构造 Integer 对象,但底层逻辑仍有关键区别:
-
Integer.valueOf("127"):先调用
parseInt得到 int 值,再走valueOf(int)流程 → 若结果落在 -128~127 内,仍命中缓存 - new Integer("127"):同样解析出 127,但直接 new 出新对象,不查缓存
- 两者都可能抛
NumberFormatException,但 valueOf 更轻量,且符合自动装箱语义
编译器与版本演进的现实影响
日常代码中几乎不会手动写 new Integer(int),因为:
- 自动装箱(如
Integer i = 100;)编译后等价于Integer.valueOf(100),天然享受缓存 - JDK 9 起
new Integer(int)已被标记为 @Deprecated,明确提示不推荐 - 即便想强制新建(极少见),也不该用已废弃的构造器,而应考虑其他方式,比如
new Integer("100")或自定义包装
本文共计602个文字,预计阅读时间需要3分钟。
Integer.valueOf(int) 是静态工厂方法,内部根据输入值决定是否复用已有对象;new Integer(int) 是构造器调用,每次执行都会在堆上分配新内存并初始化新实例。
这意味着哪怕连续写十次 new Integer(42),也会产生十个彼此不等(== 为 false)的独立对象;而十次 Integer.valueOf(42) 在默认配置下只生成一个对象,其余九次返回同一引用。
缓存池只对 valueOf() 生效
Java 规范强制要求 Integer 类内置缓存区间:-128 到 127(含)。这个缓存由 IntegerCache 静态类维护,仅被 valueOf(int) 调用路径使用。
- 在范围内(如 100):valueOf(100) 返回缓存中固定对象,节省内存和 GC 压力
- 超出范围(如 200):valueOf(200) 仍会新建对象,但仍是通过可控的工厂逻辑,未来可优化
- new Integer(100) 或 new Integer(200):一律绕过缓存,无条件新建——缓存对其完全不可见
字符串参数时的行为差异
Integer.valueOf(String) 和 new Integer(String) 都会尝试解析字符串并构造 Integer 对象,但底层逻辑仍有关键区别:
-
Integer.valueOf("127"):先调用
parseInt得到 int 值,再走valueOf(int)流程 → 若结果落在 -128~127 内,仍命中缓存 - new Integer("127"):同样解析出 127,但直接 new 出新对象,不查缓存
- 两者都可能抛
NumberFormatException,但 valueOf 更轻量,且符合自动装箱语义
编译器与版本演进的现实影响
日常代码中几乎不会手动写 new Integer(int),因为:
- 自动装箱(如
Integer i = 100;)编译后等价于Integer.valueOf(100),天然享受缓存 - JDK 9 起
new Integer(int)已被标记为 @Deprecated,明确提示不推荐 - 即便想强制新建(极少见),也不该用已废弃的构造器,而应考虑其他方式,比如
new Integer("100")或自定义包装

