Java - 装箱整数 - 为什么如果返回false则返回true

时间:2015-11-24 08:35:55

标签: java integer boxing

我正在比较两段代码

Integer x = new Integer(0), y;
y=x;
x+=0;
System.out.println(x==y); // prints false

Integer x = 0, y;
y=x;
x+=0;
System.out.println(x==y); // prints true

不应该都返回false吗?它不是原始变量,并且在第二个代码中,即使在添加零之后,它也会打印true。我知道拳击(对于从-128到127的整数),但是为什么拳击在第二段代码而不是第一段呢?

4 个答案:

答案 0 :(得分:16)

  

两者都不应该返回false吗?

该行

x += 0;

相同
x = Integer.valueOf(x.intValue() + 0);

所以你看到它使用装箱和拆箱来完成操作。

第二个例子只使用拳击,所以它按预期工作。

在第一个示例中,您明确避免使用

进行装箱
Integer x = new Integer(0);

这会强制它创建一个与盒装对象不同的新对象。

如果你这样做

Integer x = Integer.valueOf(0);

它的行为与第二个例子相同。

答案 1 :(得分:5)

不,因为-128 - 127范围内的整数正在缓存。在你的第一个例子中,你明确地创建了一个新的Integer,尽管-128 - 127范围内的每个Integer都会引用同一个对象。

如果您在第一个示例中添加了某些内容,则可以通知此内容。 请注意,这仅适用于Integer

-128 - 127 范围内
Integer x = new Integer(0), y;
Integer z = 0; // refers to the cached value.
y=x;
x+=0;
System.out.println(x==z); // This will now print true, since x+=0 will return the cached Integer.

您的第二个示例将不再有效,以及您是否将值x更改为不同的值,例如360

答案 2 :(得分:3)

[更新] 保证使用new Integer(int)始终会生成新对象,而Integer.valueOf(int)则允许使用javap来缓存值编译器,类库或JVM。

为了解释我已经编写了下面的代码并使用了javap -c <Classname>工具,命令生成下面的代码我使用了 Integer x = new Integer(0), y; y=x; x+=0; System.out.println(x==y); // prints false 来为你提供字节代码。

new

enter image description here

如果您将在上面的代码中看到它使用动态内存分配器 Integer x = 0, y; y=x; x+=0; System.out.println(x==y); // prints true 创建新对象。现在在第二种情况下如下:

valueOf

enter image description here

如Peter所说,它使用true方法,这意味着它在运行时比较同一个对象,因此它将返回==与对象比较运算符(String)。但在第一种情况下,它创建的新对象在下面的调试快照中很明显:

enter image description here

我希望这会有所帮助。 :)

顺便说一下Kevin Esche的回答也增加了这个问题。因为它基本上是对缓存对象的引用,所以在new String("some_string")的情况下尝试将它关联起来。如果您使用的是string pool,则会创建新的对象(如果可用),它将使用place。并且记住你使用的包装类不是原始的。

答案 3 :(得分:1)

由于,

整数x是一个对象。 所以==,比较参考而不是价值。

int x不是对象 所以==,比较值

您的简单代码:

Integer x = new Integer(0), y;
y=x;
x+=0;
System.out.println(x==y); // prints false
System.out.println(x.equals(y)); // prints true

int x1, y1;
x1 = 5;
y1 = x1;

System.out.println(x1==y1); // prints true
System.out.println(((Integer) x1).equals(y1)); //prints true

结果:

最好的问候

好的 - 我已经看到了javap的回复(感谢您的回答),我明白了我的想法。但是,我发现我建议的那段代码仍然很有趣。

相关问题