0

可能重复:
整数包装器对象仅在值 127 内共享相同的实例?

我有一个关于 Java 内存管理的问题。

当我尝试以下代码时:

Integer a = 1;
Integer b = 1;
System.out.println(a==b); // this gives "true" 

然而,

Integer a = 256;
Integer b = 256;
System.out.println(a==b); //this gives "false"

为什么?

非常感谢。

4

3 回答 3

6

这是因为“自动装箱”使用Integer.valueOf, 并为小整数值Integer.valueOf保留对象缓存。Integer以下是 JLS 所说的:

“如果被装箱的值 p 是真、假、一个字节或 \u0000 到 \u007f 范围内的一个字符,或者一个介于 -128 和 127(包括)之间的 int 或短数字,则令 r1 和 r2 为结果p 的任意两个拳击转换的结果。总是 r1 == r2。 JLS 5.1.7

当您使用==运算符比较一对Integer对象时,它实际上是在比较对象引用。因此true,如果拳击给了你相同的缓存Integer对象,你就会得到,false如果没有。请注意,JLS保证对所述范围的这种行为,但它也允许valueOf方法的实现以缓存更广泛的值。

底线是你应该equals(Object)用来比较Integer对象......除非你真的想测试它们是否是同一个对象。


根据我的阅读,“整数”应该在堆中创建一个“对象”,因此这两个对象应该是相同的。

如果您的代码明确执行 a new Integer(...),则可以保证创建一个新Integer对象。但是,自动装箱使用Integer.valueOf(...), 这就是实现缓存行为的地方。

于 2012-08-12T09:04:01.550 回答
2

您不应该==对对象使用引用相等 ( )。在您的第一个示例中打印为 true,因为前 128 个Integer对象由Integer类缓存。采用.equals()

于 2012-08-12T09:03:24.217 回答
0

当值大于数据表示的范围时,它们是不同的对象,因为它们被包装了。您现在正在像对象 ID 一样进行比较。

You are comparing objects' addresses
于 2012-08-12T09:02:56.713 回答