使用 Integer 包装器类创建了多少个对象?

2022-08-31 16:30:14
Integer i = 3; 
i = i + 1; 
Integer j = i; 
j = i + j; 

由于上述示例代码中的语句,创建了多少个对象,为什么?是否有任何 IDE 可以在其中查看创建了多少个对象(可能处于调试模式)?


答案 1

令人惊讶的是,答案是零。

从 -128 到 +127 的所有 s 都由 JVM 预先计算。Integer

您的代码创建对这些现有对象的引用


答案 2

严格正确的答案是,创建的对象数量是不确定的。它可能介于 0 和 3 之间,或者介于 2561 之间,甚至更多介于 2 之间,具体取决于Integer

  • Java平台3
  • 这是否是第一次执行此代码,以及
  • (潜在地)其他依赖于值装箱的代码是否在它之前运行4.int

-128 到 127 的值并不严格要求预先计算。实际上,指定 Boxing 转换的 JLS 5.1.7 是这样说的:Integer

如果装箱的值 p 是介于 -128 和 127 (包括 §3.10.1) 之间的 int 类型的整数文本...则让 a 和 b 成为 p 的任意两个装箱转换的结果。a == b 总是这样。

需要注意的两点:

  • JLS 仅对>>字<<要求这样做。
  • JLS 不强制要求对值进行预先缓存。惰性缓存也满足了 JLS 的行为要求。

甚至 javadoc 也没有指定预先缓存结果。Integer.valueof(int)

如果我们检查从 Java 6 到 8 的 Java SE 源代码,很明显,当前的 Java SE 实现策略是预先计算这些值。但是,由于各种原因(见上文),这仍然不足以让我们对“多少个对象”的问题给出明确的答案。java.lang.Integer


1 - 如果执行上述代码触发了 Java 版本中 Integer 的类初始化,则在类初始化期间缓存被紧急初始化,则可能是 256。

2 - 如果高速缓存大于 JVM 规范要求,则可能更多。在某些版本的 Java 中,可以通过 JVM 选项增加高速缓存大小。

3 - 除了平台实现装箱的一般方法之外,编译器还可以发现部分或全部计算可以在编译时完成或完全优化它。

4 - 此类代码可能会触发整数缓存的延迟或预先初始化。