可能重复:
整数包装器对象仅在值 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"
为什么?
非常感谢。
可能重复:
整数包装器对象仅在值 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"
为什么?
非常感谢。
这是因为“自动装箱”使用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(...)
, 这就是实现缓存行为的地方。
您不应该==
对对象使用引用相等 ( )。在您的第一个示例中打印为 true,因为前 128 个Integer
对象由Integer
类缓存。采用.equals()
当值大于数据表示的范围时,它们是不同的对象,因为它们被包装了。您现在正在像对象 ID 一样进行比较。
You are comparing objects' addresses