2015-11-02 54 views
3

通常情況下,在Java庫對象的引用,不能使用==比較,但我只是檢查:當它們是.equals()時,Java整數總是==嗎?

Integer x = 5; 
Integer y = x + 1; 
Integer z = y - 1; 
x.equals(z) 
true (boolean) 
x == z 
true (boolean) 

是,僅僅我的IDE的神器,或者是Java Integer對象保證指向相同的整數,當他們有相同的價值?後者的保證會簡化我正在寫的一些代碼。

+0

對於所有1個字節的數字是肯定的,因爲JLS要求它。嘗試更大的數字。此外,如果你明確地生成整數,那麼顯然你的運氣不好,這個保證只適用於自動裝箱 – Voo

+1

與所有「價值對象」一樣,你不應該依賴對象身份。 –

+0

@resueman在你的例子中你使用自動混合? – Voo

回答

7

當它們是.equals()時,Java整數總是==嗎?

號在正常情況下,試圖數值的比較,當你不能依靠==Integer實例。爲此,您必須在比較之前將它們解包至int或使用equals

在您的示例中,您看到的是JDK緩存並重復使用有限數量的Integer實例(對於代表-128至127的Integers)。從Integer.valueOf(int)

此方法將始終緩存範圍-128至127(含)範圍內的值,並可緩存此範圍之外的其他值。

現在,您的代碼使用裝箱轉換,而不是Integer.valueOf和規範doesn't say拳擊轉換使用Integer.valueOf,但它很可能是這是他們做什麼(在效果;例如,兩個拳擊轉換和Integer.valueOf使用相同的底層機制和緩存)。

你可以看到,==是不可靠的Integer情況下,如果你使用一個不同的值:(live copy

Integer x = 524; // <==== Changed 
Integer y = x + 1; 
Integer z = y - 1; 
System.out.println("equals? " + x.equals(z)); 
System.out.println("==? " + (x == z)); 

輸出(也許,這就是我得到IDEOne,但同樣的文件說Integer可能緩存中的其他值):

 
equals? true 
==? false 
+2

不知道爲什麼有人會倒下顯然正確的答案 – Voo

2

並不總是,但對於特定的範圍。

也趕上這裏是Java捕捉整數值的範圍從-128到127。因此,他們返回時,你做真正的==

這裏是相同

http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7

語言規範

如果值p被裝箱爲真,假,字節或範圍在\ u0000到\ u00f之間的字符,或者介於-128和127之間的整數或短數字,則讓r1和r2爲任何兩次拳擊轉換的結果。 r1 == r2總是如此。

我記得原因是爲了實現小設備的性能。

2

不,它不能保證。對於某些值(特別是較小,更常用的值),該值將被內部化並且相同的對象引用將被重用。如果你使用3,279,831進行同樣的測試,它可能會返回錯誤。

相關問題