• 作者:老汪软件技巧
  • 发表时间:2024-08-21 10:02
  • 浏览量:

听到这个问题的一瞬间,我的第一反应是:“口误吧?127和128肯定不一样啊~”,哈哈,你的呢?

其实这是一道大厂经典面试题,它触及了 Java 中 Integer 对象的创建和缓存机制的一个微妙之处。

一、new Integer("127")总是在堆内存中创建一个新的 Integer 对象。值为 127。不使用整数缓存池。二、Integer.valueOf("128")创建一个新的 Integer 对象,值为 128。不使用整数缓存池,因为 128 超出了默认缓存范围。三、主要区别1、对象创建

两种方式在这个例子中都会创建新对象。

2、缓存使用

new Integer("127") 不使用缓存。

Integer.valueOf("128") 也不使用缓存,但原因不同(超出范围)。

3、性能和内存:

在这个特定例子中,两者的性能和内存使用基本相同。

4、值的考虑:

127 在缓存范围内,但 new 关键字绕过了缓存。

128 超出缓存范围,所以 valueOf 方法会创建新对象。

四、对比示例

Integer a = new Integer("127");
Integer b = new Integer("127");
System.out.println(a == b);  // false
Integer c = Integer.valueOf("127");
Integer d = Integer.valueOf("127");
System.out.println(c == d);  // true
Integer e = Integer.valueOf("128");
Integer f = Integer.valueOf("128");
System.out.println(e == f);  // false

五、为什么说Integer.valueOf("128") 也不使用缓存,是因为超出了范围?1、Integer 缓存是什么?

Java 的 Integer 类维护了一个内部缓存,用于存储经常使用的整数值。这个缓存就像一个预先准备好的数字集合。

默认情况下,这个缓存包含了 -128 到 127 之间的所有整数。

这个范围是经过 Java 开发者仔细考虑后选定的,因为这个范围内的数字在日常编程中使用频率最高。

2、为什么是 -128 到 127?字节范围: 这个范围恰好对应一个字节(byte)可以表示的整数范围。常用数字: 大多数日常计算和循环中使用的小整数都在这个范围内。内存权衡: 缓存范围不能太大,否则会占用过多内存。3、为什么 128 不在缓存中?

128 刚好超出了这个预定义的范围。

当你调用 Integer.valueOf("128") 时,Java 会检查这个数字是否在缓存范围内。

发现 128 超出范围后,Java 就会创建一个新的 Integer 对象,而不是使用缓存。

4、代码示例

Integer a = Integer.valueOf("127"); // 使用缓存
Integer b = Integer.valueOf("127"); // 使用缓存
System.out.println(a == b); // 输出 true,因为是同一个缓存对象
Integer c = Integer.valueOf("128"); // 不使用缓存,创建新对象
Integer d = Integer.valueOf("128"); // 不使用缓存,再次创建新对象
System.out.println(c == d); // 输出 false,因为是两个不同的对象

5、可以改变缓存范围吗?

是的,可以通过 JVM 参数 -XX:AutoBoxCacheMax= 来增加上限。

但是,下限 -128 是固定的,不能改变。

6、Integer对象比较

不要依赖于缓存机制来比较整数对象。

始终使用 .equals() 方法来比较 Integer 对象的值。

六、结论

虽然在给定的例子中("127" 和 "128"),两种方法都会创建新对象,但它们的行为原因不同:

new Integer("127") 总是创建新对象,无论值是多少。

Integer.valueOf("128") 创建新对象是因为 128 超出了缓存范围。

在实际应用中,除非特别需要新对象,否则推荐使用 Integer.valueOf() 或自动装箱,以便在可能的情况下利用缓存优化。

虽然了解这些细节很重要,但在日常编程中,我们应该专注于编写清晰、正确的代码,而不是过度依赖于这些底层优化。正确使用 .equals() 进行值比较,以及优先使用 valueOf() 或自动装箱,通常就足以编写高效且可靠的代码。