2012-04-03 32 views
24

跟我走..比較整數值在Java中,行爲怪異

Integer x = 23; 
Integer y = 23; 

if (x == y) 
    System.out.println("what else");  // All is well as expected 
else 
    System.out.println("..."); 

雖然

Integer x = someObject.getIndex(); 
Integer y = someOtherObject.getSomeOtherIndex(); 

if (x == y) 
    System.out.println("what else"); 
else 
    System.out.println("...");  // Prints this 

嗯...我儘量鑄造爲int

int x = someObject.getIndex(); 
int y = someOtherObject.getSomeOtherIndex() 

if (x == y)  
    System.out.println("what else"); // works fine 
else 
    System.out.println("..."); 

是他們都整型?

System.out.println(x.getClass().getName());    // java.lang.Integer 
System.out.println(y.getClass().getName());    // java.lang.Integer 
System.out.println(someObject.getIndex());    // java.lang.Integer 
System.out.println(someOtherObject.getSomeOtherIndex()); // java.lang.Integer 

你們認爲什麼?什麼會解釋這樣的事情?

+0

可能重複【如何=運算符和==操作符在Java中?](http://stackoverflow.com/questions/9824053/how-operator-and-operator-works-in-java) – assylias 2012-04-03 22:08:07

+0

getIndex();和getSomeOtherIndex()是做什麼的? – 2016-02-17 12:08:42

+0

[爲什麼128 == 128返回false,但是127 == 127在轉換爲Integer包裝器時返回true?](https://stackoverflow.com/questions/1700081/why-does-128-128-return- false-127-127-return-true-when-convert-to-integ) – Tom 2018-02-05 16:17:28

回答

42

您在比較Integer值,它們是參考值。你通過自動裝箱提出這些參考。對於某些值(保證-128到127),JRE維護一個Integer對象的緩存。對於更高的值,它不會。從section 5.1.7 of the JLS

如果被裝箱值p爲真,假,字節,或在範圍\ u0000的一個char到\ u007f,或-128和127之間int或短號碼(含),那麼讓r1和r2是p的任何兩個裝箱轉換的結果。 r1 == r2總是如此。

理想情況下,裝箱給定的原始值p將始終產生相同的參考。實際上,使用現有的實現技術可能不可行。上述規則是務實的妥協。上面的最後一個條款要求某些常用值總是被裝入不可區分的對象中。實現可能會緩存這些,懶惰或熱切。對於其他值,該公式不允許對程序員的盒裝值的身份進行任何假設。這將允許(但不要求)分享部分或全部這些參考文獻。

這可以確保在大多數情況下,行爲將成爲所需的行爲,而不會對性能造成不必要的損失,特別是在小型設備上。例如,內存限制較少的實現可能會緩存所有char和short值,以及-32K到+ 32K範圍內的int和long值。

寓意:當你感興趣的潛在int值不比較Integer引用。使用.equals()或先獲取int值。

+2

@JAM:是的,或者轉換爲int,調用intValue()並比較結果,或者調用equals '。 – 2012-04-03 22:04:29

+1

好酷;謝謝喬恩! – JAM 2012-04-03 22:07:24

1

聽起來當您使用在兩個整數==喜歡的事,是時髦與自動裝箱。

我會假設它使用Integer如果使用equals()方法時能正常工作?無論如何,這是我的猜測。

您沒有使用Java 1.4或東西是你嗎?

+0

其他答案顯示了爲什麼會發生這種情況:JVM緩存整數的小值。所以,當我比較時(新Integer(12)==新Integer(12))[產生true],JVM返回SAME緩存對象的值爲12的兩側。因此,實際上對象是相同的。對於較大的值,將創建獨立的新對象,但這不會發生。 – ingyhere 2013-12-14 19:25:09

13

要正確比較整數,您需要使用.equals()或通過投射到int或在其上調用intValue()比較它們的原始值。

使用==檢查是否兩個整數是相同對象,它們不是否包含相同的數值

Integer a = new Integer(1); 
    Integer b = new Integer(1); 

    System.out.println(a.equals(b));     //true 
    System.out.println((int)a == (int)b);    //true 
    System.out.println(a.intValue() == b.intValue()); //true 
    System.out.println(a == b);      //false 

編輯從JLS解釋關於自動裝箱喬恩的觀點:

Integer a = 1; 
    Integer b = 1; 
    System.out.println(a.equals(b));     //true 
    System.out.println((int)a == (int)b);    //true 
    System.out.println(a.intValue() == b.intValue()); //true 
    System.out.println(a == b);      //true 

對!

Integer a = 128; 
    Integer b = 128; 
    System.out.println(a.equals(b));     //true 
    System.out.println((int)a == (int)b);    //true 
    System.out.println(a.intValue() == b.intValue()); //true 
    System.out.println(a == b);      //false