128陷阱
核心定义
128陷阱是java中Integer包装类自动装箱时的一个典型现象。
当通过自动装箱创建-128-127范围内的Integer对象时,会复用常量池中的缓存对象;超出该范围时,会创建新的对象。
直接用==比较超出范围的Integer对象时,会出现"值相等但==判断为false"的情况。
这就是128陷阱,本质是-128-127的缓存机制导致的。
原理分析
java为了优化性能,在Integer类中维护了一个IntegerCache缓存池,默认存储-128-127的Integer对象:
- 当执行Integer a = 100;(自动装箱)时,底层调用Integer.valueOf(100),直接返回缓存池中的对象;
- 当执行Integer b = 200;时,Integer.valueOf(200)会创建新的Integer对象,而非复用缓存;
- ==比较的是对象的内存地址,因此:
- Integer a = 127; Integer b = 127; -> a == b -> true(复用缓存,地址相同);
- Integer a = 128; Integer b = 128; -> a == b -> false(新建对象,地址不同)。
代码示例
java
public class Integer128Test {
public static void main(String[] args) {
// 127在缓存范围内,复用对象
Integer a = 127;
Integer b = 127;
System.out.println(a == b); // 输出true
// 128超出缓存范围,创建新对象
Integer c = 128;
Integer d = 128;
System.out.println(c == d); // 输出false
// 正确的比较方式:用equals(比较值)
System.out.println(c.equals(d)); // 输出true
}
}
输出:

扩展说明
- 缓存范围可以通过JVM参数调整上限(但下限固定为-128);
-XX:AutoBoxCacheMax = <size>
- 不仅Integer,Byte、Boolean(全部缓存)、Short/Long(-128-127缓存)也有类似的缓存机制,Character缓存为0-127。
- 这种缓存机制能够减少内存消耗,提高性能。
==和equals的区别
核心区别总结

分场景详细解释
1.==使用规则
- 基本数据类型(如 int、double、char) :直接比较值是否相等
java
int a = 10;
int b = 10;
System.out.println(a == b); // true
- 引用数据类型(如 Object、String、自定义类) :比较对象的内存地址是否相等(即是否为同一个对象)
java
String s1 = new String("test");
String s2 = new String("test");
System.out.println(s1 == s2); // false(两个不同对象,地址不同)
2.equals使用规则
- 默认实现(Object 类) :底层就是用
==比较地址
java
public boolean equals(Object obj) {
return (this == obj);
}
- 重写后(如 String、Integer) :改为比较对象的实际值
java
String s1 = new String("test");
String s2 = new String("test");
System.out.println(s1.equals(s2)); // true(比较字符串内容)
Integer i1 = new Integer(100);
Integer i2 = new Integer(100);
System.out.println(i1.equals(i2)); // true(比较数值)
- 自定义类 :若未重写
equals(),则沿用 Object 的地址比较;若需比较对象属性,需手动重写
java
class User {
private String name;
private int age;
// 重写equals,比较name和age
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return age == user.age && Objects.equals(name, user.name);
}
}
总结
- 128 陷阱 :核心是
IntegerCache缓存池导致-128-127的Integer复用对象,超出范围新建对象,因此比较Integer值时务必用equals()而非==。 - == vs equals :
==是运算符,基本类型比数值、引用类型比地址;equals()默认比地址,重写后(如 String)比实际值,引用类型比较内容时优先用equals()。