integer缓存范围为-128至127,该范围内==比较返回true(复用同一对象),范围外返回false(新建不同对象);应统一使用equals()或intvalue()比较值。

因为 == 比较的是对象引用(内存地址),而超出缓存范围的 Integer 对象是各自独立创建的,地址不同。
Integer 的缓存机制决定了地址是否复用
Java 为提升性能,在 Integer 类内部维护了一个静态缓存数组(IntegerCache),默认覆盖范围是 -128 到 127。在这个区间内,每次调用 Integer.valueOf(100) 或直接赋值 Integer i = 100,都会复用缓存中已有的同一个对象。
-
Integer a = 127;和Integer b = 127;→ 指向同一块内存 →a == b为 true -
Integer c = 128;和Integer d = 128;→ 分别调用new Integer(128)→ 不同内存地址 →c == d为 false
超出范围时实际发生了什么
查看 Integer.valueOf() 源码逻辑:
- 若传入值在
[low, high](默认 -128 ~ 127)内,直接返回缓存数组中的已有实例 - 否则,执行
new Integer(value),每次新建一个堆对象
所以 128 == 128 看似数值相同,但两个 Integer 是不同对象,== 自然返回 false。
为什么不能依赖 == 做值比较
== 的行为取决于对象创建方式,不可靠:
-
Integer x = new Integer(100); Integer y = 100;→x == y是 false(一个是 new 出来,一个走缓存) - 即使数值相同,只要有一个是
new创建,==就大概率失败 - 缓存上限可通过 JVM 参数调整(如
-Djava.lang.Integer.IntegerCache.high=200),但业务代码不该依赖这种可变配置
正确做法:统一用 equals 或拆箱比较
要判断数值是否相等,应使用以下任一方式:
-
a.equals(b)—— 安全、语义明确,推荐 -
a.intValue() == b.intValue()—— 拆箱后比基本类型,高效且不会空指针(前提是 a、b 非 null) - 如果确定非 null 且追求极致性能,也可用
(int)a == (int)b(自动拆箱)
避免把 == 当作“值相等”用,这是包装类最常见也最隐蔽的坑之一。











