java 整数 i=3 与整数 i= 新整数 (3)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17494176/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Integer i=3 vs Integer i= new Integer (3)
提问by Shruti Rawat
I am comparing 2 pieces of code. First
我正在比较 2 段代码。第一的
Integer i=3;
Integer j=3;
if(i==j)
System.out.println("i==j"); //prints i==j
Second,
第二,
Integer i=3;
Integer j=new Integer(3);
if(i==j)
System.out.println("i==j"); // does not print
I have doubt that in the first snippet why i==j
is being printed? Shouldn't the references be different?
我怀疑在第一个片段中为什么i==j
要打印?参考文献应该不一样吧?
回答by Jon Skeet
It's to do with how boxing works. From the JLS section 5.1.7:
这与拳击的工作方式有关。从JLS 部分 5.1.7:
If the value p being boxed is true, false, a byte, or a char in the range \u0000 to \u007f, or an int or short number between -128 and 127 (inclusive), then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.
如果被装箱的值 p 是真、假、一个字节或一个 \u0000 到 \u007f 范围内的字符,或者一个 int 或介于 -128 和 127(含)之间的短数,则让 r1 和 r2 为p 的任意两个拳击转换。r1 == r2 总是如此。
Basically, a Java implementation mustcache the boxed representations for suitably small values, and maycache more. The ==
operator is just comparing references, so it's specifically detecting whether the two variables refer to the same object. In the second code snippet they definitely won't, as new Integer(3)
definitely isn't the same reference as any previously created one... it always creates a new object.
基本上,Java 实现必须缓存适当小的值的装箱表示,并且可能缓存更多。该==
运营商只是比较引用,所以它的特异性检测两个变量是否指向同一个对象。在第二个代码片段中,他们绝对不会,因为new Integer(3)
绝对不是与以前创建的任何引用相同的引用......它总是创建一个新对象。
Due to the rules above, this code must always give the same result:
由于上述规则,此代码必须始终给出相同的结果:
Integer x = 127;
Integer y = 127;
System.out.println(x == y); // Guarantee to print true
Whereas this could go either way:
而这可以是任何一种方式:
Integer x = 128;
Integer y = 128;
System.out.println(x == y); // Might print true, might print false
回答by zerocool
Java pools integers between -128 and 127 and hence both the references are the same.
Java 将 -128 和 127 之间的整数池化,因此两个引用是相同的。
Integer i=3;
Integer j=3;
This results in autoboxing and 3 is converted to Integer 3. So for i is referring to an Integer object that is in constant pool, now when you do j=3, the same reference as that of i is assigned to j.
这导致自动装箱并且 3 被转换为整数 3。所以因为 i 指的是常量池中的一个整数对象,现在当你做 j=3 时,与 i 相同的引用被分配给 j。
Whereas below code:
而下面的代码:
Integer j=new Integer(3);
always results in a new Integer creation, in heap. This is not pooled. And hence you see that both reference are referring to different objects. Which results in
总是导致在堆中创建一个新的整数。这不是汇集的。因此,您会看到两个引用都指向不同的对象。这导致
Integer i=3;
Integer j=new Integer(3);
if(i==j)
System.out.println("i==j"); // **does not print**
回答by Vishal K
I have doubt that in the first snippet why i==j is being printed? Shouldn't the references be different?
我怀疑在第一个片段中为什么要打印 i==j?参考文献应该不一样吧?
Because,
因为,
Integer i=3;
Integer j=3;
are internally using Integer#valueOf()to perform autoBoxing
. And oracle doc says about valueOf()
method that:
在内部使用Integer#valueOf()来执行autoBoxing
. oracle doc 关于valueOf()
方法的说明:
Returns an Integer instance representing the specified int value. If a new Integer instance is not required, this method should generally be used in preference to the constructor Integer(int), as this method is likely to yield significantly better space and time performance by caching frequently requested values. This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.
返回表示指定 int 值的 Integer 实例。如果不需要新的 Integer 实例,则通常应优先使用此方法而不是构造函数 Integer(int),因为此方法通过缓存频繁请求的值可能会产生明显更好的空间和时间性能。此方法将始终缓存 -128 到 127(含)范围内的值,并且可能缓存此范围之外的其他值。
Since the value 3
is cached therefore, both variables i
and j
are referencing the same object. So, i==j
is returning true
. Integer#valueOf()
uses flyweight pattern.
由于该值3
因此被缓存,两个变量i
和j
都引用同一个对象。所以,i==j
正在返回true
。Integer#valueOf()
使用享元模式。
回答by Ravi Thapliyal
Integer i=3;
Integer j=3;
if(i==j)System.out.println("i==j");
Here, 3
is being auto-boxed and hence i
and j
point to the same Integer
.
在这里,3
被自动装箱,因此i
并j
指向相同的Integer
。
Integer i=3;
Integer j=new Integer(3);
if(i==j)System.out.println("i==j"); // does not print
Here, i
points to the auto-boxed Integer
whereas j
points to a new Integer
and hence there references fail the equals ==
operator test.
在这里,i
指向自动装箱Integer
而j
指向新的Integer
,因此引用未通过等于==
运算符测试。
But, here's some more food for thought.
但是,这里还有一些值得深思的地方。
Integer i=300;
Integer j=300;
if(i!=j)System.out.println("i!=j"); // prints i!=j
Why? Because, auto-boxing shares Integer
instances between -128 to 127 only. This behaviour, however, may differ between different Java implementations.
为什么?因为,自动装箱Integer
仅在 -128 到 127 之间共享实例。但是,这种行为可能因不同的 Java 实现而异。
回答by Ingo
No they shouldn't, because java can use pre-fabricated Integer objects for small numbers when autoboxing.
不,他们不应该,因为 java 可以在自动装箱时为小数字使用预制的 Integer 对象。
回答by emphywork
In Following Piece of Code:
在以下代码中:
Integer i=3;
Integer j=3;
if(i==j)
System.out.println("i==j");
Here, "==" compares reference with each other rather than the value. So, Integer i and j both are referring to same reference in the memory.
这里,“==”比较的是引用而不是值。因此,整数 i 和 j 都指的是内存中的相同引用。
while in Following Piece of Code:
在以下代码段中:
Integer i=3;
Integer j=new Integer(3);
if(i==j)
System.out.println("i==j");
The reference to both values are changed because 'j' is newly created object/reference of Integer in memory while 'i' is just referring to a value.
对这两个值的引用都已更改,因为“j”是内存中新创建的 Integer 对象/引用,而“i”仅引用一个值。
Therefore, the output of 1st code is "i==j" and 2nd code does not have any output.
因此,第一个代码的输出是“i==j”,第二个代码没有任何输出。
Hope this helps.
希望这可以帮助。
回答by Dancrumb
In a similarfashion to strings, when autoboxing is used, such as in
以类似于字符串的方式,当使用自动装箱时,例如在
Integer i = 3;
Integer j = 3;
Java can draw from a pool of prefabricated objects. In the case of j
, there's already an Integer
instance representing the value of 3
in the pool, so it draws from that. Thus, i
and j
point to the same thing, thus i == j
.
Java 可以从预制对象池中提取。在 的情况下j
,池中已经有一个Integer
代表 的值的实例3
,因此它从中提取。因此,i
和j
指向同一事物,因此i == j
。
In your second example, you're explicitly instantiating a new Integer
object for j
, so i
and j
point to different objects, thus i != j
.
在您的第二个示例中,您显式实例化了一个新Integer
对象 for j
, soi
并j
指向不同的对象,因此i != j
.
回答by huseyin tugrul buyukisik
Interpreter/JIT optimizer can put all 3's in same box. But if you force a "new" then you get another address.
解释器/JIT 优化器可以将所有 3 放在同一个框中。但是如果你强制一个“新”,那么你会得到另一个地址。
Try
尝试
j=8; // after initialization of i and j
then see the j's address changed for first version.
然后看到第一个版本的 j 的地址发生了变化。
回答by William Morrison
Because in the second peice of code your first integer is being auto-boxed while the second is not.
因为在第二段代码中,您的第一个整数被自动装箱,而第二个则不是。
This means a new Integer instance is being created on the fly. These 2 object instances are different. The equality check will return false there as the two instances are actually different pieces of memory.
这意味着正在动态创建一个新的 Integer 实例。这两个对象实例是不同的。相等检查将在那里返回 false,因为这两个实例实际上是不同的内存。