2015-11-24 64 views
6

我比較兩段代碼爪哇 - 拳擊整數 - 爲什麼它返回true,如果應該返回false

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),但是爲什麼拳擊在第二段代碼而不是在第一段?

+1

不,因爲在'-128 - 127'範圍內的Integer會被緩存。在你的第一個例子中,你明確地創建了一個新的'Integer',儘管每個'Integer'在'-128 - 127'範圍內都會引用同一個對象。 – SomeJavaGuy

+0

儘管還有其他回答說-128-127不是教條,它只是JVM的一個功能,可以在一些版本中使用-Djava.lang.Integer.IntegerCache.high屬性進行調整,默認值可能與JVM到JVM,**你永遠不應該依賴這種行爲!**請參閱http:// stackoverflow。com/questions/15052216/how-large-is-the-integer-cache –

回答

16

不應該都返回false?

x += 0; 

相同

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

讓你看到它使用裝箱和拆箱來完成操作。


第二個示例僅使用裝箱,因此它按預期工作。

在第一個例子,你明確地避免裝箱與

Integer x = new Integer(0); 

這迫使它來建立一個新的對象,它是對裝箱對象不同。

如果你

Integer x = Integer.valueOf(0); 

它的行爲一樣的第二個例子。

+0

也許如果編譯器足夠聰明,它可能會忽略增加'0'? – TheLostMind

+0

@VinodMadyalkar是的,但它有這樣的副作用。 Java很不情願地打破兼容性,即使它沒有太大的意義恕我直言。注意:'x + = 0f'確實對某些值做了一些事情,或許令人驚訝。 –

+0

我在評論之前就已經想過了。但是編譯器肯定可以在正常情況下(比如在問題中)做:)。這可能會阻止幾個字節碼指令 – TheLostMind

5

不,因爲在-128 - 127範圍內的整數正在緩存。在第一個示例中,您明確地創建了一個新的整數,儘管-128 - 127範圍內的每個整數都會引用同一個對象。

如果您在第一個示例中添加了某些內容,則可以通知您。 通知,這將只在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

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的(感謝您的答案)的響應,我明白我錯過了。但是,我發現我提出的一段代碼仍然很有趣。

+1

我想你沒有得到提問者問題的本質。他很驚訝,爲什麼第二個例子返回true。 – Michal

3

[更新]使用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 

enter image description here

如果你在上面的代碼中看到它創建了動態內存分配是new新的對象。現在,在如下第二種情況:

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

enter image description here

如由Peter說,它使用valueOf方法這意味着它是比較在運行時相同的對象,以便它將返回true與對象比較運算符(==)。但是,在第一種情況下它是創造新的對象,它是在下面的調試快照顯眼:

enter image description here

我希望這有助於。 :)

順便凱文埃斯凱答案也增加了這個問題。因爲它基本上引用了緩存對象,所以嘗試在String的情況下將其與它關聯。如果您使用的是new String("some_string"),則會創建新對象,如果可用,則將使用string pool。並且記住你正在使用不是原始的包裝類。

相關問題