我正在比较两段代码
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的整数),但是为什么拳击在第二段代码而不是第一段呢?
答案 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
如果您将在上面的代码中看到它使用动态内存分配器 Integer x = 0, y;
y=x;
x+=0;
System.out.println(x==y); // prints true
创建新对象。现在在第二种情况下如下:
valueOf
如Peter所说,它使用true
方法,这意味着它在运行时比较同一个对象,因此它将返回==
与对象比较运算符(String
)。但在第一种情况下,它创建的新对象在下面的调试快照中很明显:
我希望这会有所帮助。 :)
顺便说一下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的回复(感谢您的回答),我明白了我的想法。但是,我发现我建议的那段代码仍然很有趣。