在 Java 开发中,整数池(Integer Cache)机制是一个容易被忽视但可能引发 bug 的细节,特别是与 Integer 自动装箱和 == 运算符相关的 128 陷阱。本文将深入解析 Java 128 陷阱的原理、影响以及如何避免此类问题。
1. 何为 Java 128 陷阱?
在 Java 中,整数缓存(Integer Cache)会缓存 -128 到 127 之间的 Integer 对象。当我们使用自动装箱(Autoboxing)时,如果数值在这个范围内,Java 会返回相同的 Integer 对象,而不会创建新的对象。
Integer a = 100;
Integer b = 100;
System.out.println(a == b);
运行结果是:true
然而,一旦超出 127,Java 会创建新的 Integer 对象:
Integer x = 1000;
Integer y = 1000;
System.out.println(x == y);
运行结果是:false
这里 x == y 结果为 false,是因为 1000 不在缓存范围内,因此 x 和 y 是两个不同的 Integer 对象,== 比较的是对象引用,而不是值。
2. 为什么 Java 设计 Integer Cache?
Integer Cache 的主要目的是提升性能和减少内存使用:
1.Java 中整数对象是不可变的(Immutable),多个变量共享相同的对象不会有副作用。
2.在 -128 到 127 这个常用范围内,复用 Integer 对象可减少内存开销,提高性能。
Integer中的valueOf源码:

IntegerCache源码:

3. 128 陷阱的常见坑点
(1)== 运算符 和 .equals()
使用 == 比较对象时,它比较的是引用地址,而 equals() 比较的是值。
Integer c = 1000;
Integer d = 1000;
System.out.println(c == d);
System.out.println(c.equals(d));
![]()
正确的做法:在需要比较值时,应该使用 .equals() 而非 ==。
(2)自动装箱与基本数据类型
当 Integer 和 int 进行 == 比较时,Java 会自动拆箱(unboxing),转换成基本数据类型 int,因此不会受到 Integer 缓存的影响:
Integer f = 128;
int g = 128;
System.out.println(f == g);
![]()
原因:a 被自动拆箱为 int,然后与 b 进行值比较。
(3)使用 Integer.valueOf()
Integer.valueOf() 方法会利用 Integer 缓存,而 new Integer() 则始终创建新对象。
Integer a = Integer.valueOf(127);
Integer b = Integer.valueOf(127);
System.out.println(a == b);
Integer x = new Integer(127);
Integer y = new Integer(127);
System.out.println(x == y);

最佳实践:使用 Integer.valueOf() 代替 new Integer()。
4. 如何避免 128 陷阱?
1.始终使用 .equals() 进行值比较
2.避免不必要的装箱和拆箱
直接使用基本数据类型 int 进行比较,可以避免 Integer 引起的陷阱。
3.使用 Integer.valueOf() 复用缓存对象
1069

被折叠的 条评论
为什么被折叠?



