我正在比较两段代码
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吗?它不是原生变量,在第二段代码中,即使在添加了0之后,它也会输出true。我知道装箱(从-128到127的整数),但是为什么装箱在第二段代码中工作,而不是在第一段代码中工作?
发布于 2015-11-24 16:39:06
不应该都返回false吗?
这条线
x += 0;等同于
x = Integer.valueOf(x.intValue() + 0);所以你可以看到它使用装箱和拆箱来完成操作。
第二个示例仅使用装箱,因此它的工作方式与预期一致。
在第一个示例中,显式避免使用
Integer x = new Integer(0);这迫使它创建一个不同于已装箱对象的新对象。
如果你这样做了
Integer x = Integer.valueOf(0);它的行为将与第二个示例相同。
发布于 2015-11-24 16:42:08
不会,因为-128 - 127范围内的整数将被缓存。在您的第一个示例中,您显式地创建了一个新的Integer,尽管-128 - 127范围内的每个Integer将引用相同的对象。
如果您在第一个示例中添加了某些内容,则可以通知这一点。请注意,这只能在-128 - 127的Integer范围内工作
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,那么第二个示例也不会再起作用
发布于 2015-11-24 17:21:15
使用new Integer(int)的更新保证总是产生一个新对象,而Integer.valueOf(int)允许值的缓存由编译器、类库或JVM完成。
为了解释一下,我写了下面的代码,并使用javap工具,命令来生成下面的代码,我使用了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

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

我希望这能帮到你。:)
顺便说一句,Kevin Esche answer也增加了这个问题。因为它基本上是对缓存对象的引用,所以在String的情况下尝试将其关联起来。如果你使用的是new String("some_string"),它将创建新的对象,如果可用,它将从string pool中使用。请记住,您使用的是包装器类,而不是原始类。
https://stackoverflow.com/questions/33888841
复制相似问题