2010-03-23 114 views
10
Integer i = 127; 
Integer j = 127; 
System.out.println(i == j); 
System.out.println(i.equals(j)); 

Integer i1 = 128; 
Integer j1 = 128; 
System.out.println(i1 == j1); 
System.out.println(i1.equals(j1)); 

我不明白爲什麼它不打印「真實,真實,真實,真實」。請給答案?以下代碼輸出「true,true,false,true」。它不應該是「真實,真實,真實,真實」嗎?

+2

這樣一個具體問題,嗯,可疑 – Will 2010-03-23 13:01:06

+1

@Will我在一本SCJP書中看到過同樣的問題 – 2010-03-23 13:07:10

+1

我敢打賭,它返回false,true,false,true而不是true,true,false,true – 2010-03-23 13:10:18

回答

29

當您使用==時,您將比較對象實例的相等性。

之所以在前兩種情況下都是平等的,你通過自動裝箱(而不是調用new Integer(127))創建的Integers,和Java Language Specification §5.1.7要求Integers和127之間-128緩存。

實現可以緩存比這更多的值,但不是必需的;顯然你使用的JVM不會緩存128. Sun Java 6的情況就是這樣。

5

Integer是一個類。如果你輸入新的Integer(),你創建一個新的對象。所以我,j,i1和j1都是不同的對象。如果你使用==,它只對同一個對象有效。對於小於128的整數,JVM始終使用相同的對象,以便輸出爲true。

4

沒有它不應該:

Integer i1 = 128; 
Integer j1 = 128; 

自動裝箱導致了Java的實現,它使用的是要創建兩個不同的Integer對象。

如果整數值在-128到127的範圍內,那麼JLS指出將使用相同的Integer對象;見JLS 1.5.7。但是,JLS確實要求而不是要求i1i2必須具有該範圍以外的不同值。事實上,JLS中的以下討論說:

理想情況下,對給定的原始值p進行裝箱將始終產生相同的引用。實際上,使用現有的實現技術可能不可行。上述規則是務實的妥協。上面的最後一個條款要求某些常用值總是被裝入不可區分的對象中。實現可能會緩存這些,懶惰或熱切。

對於其他值,此公式不允許對程序員的盒裝值的身份作任何假設。這將允許(但不要求)分享部分或全部這些參考文獻。

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

+0

的難題之一你如何拼寫英文2? – 2010-03-23 13:05:08

+0

@PP - 它必須在睡覺之後:-) – 2010-03-23 13:13:56

+0

如果我沒有記錯的話,Sun Java 7將會有一個可配置的Integer緩存。我認爲這對某些基準測試非常有幫助。 – 2010-03-23 13:14:50

9

只是添加到其他所有的正確答案,看看在source code,以充分了解@mmyers在說:

584  /** 
    585  * Returns an {@code Integer} instance representing the specified 
    586  * {@code int} value. If a new {@code Integer} instance is not 
    587  * required, this method should generally be used in preference to 
    588  * the constructor {@link #Integer(int)}, as this method is likely 
    589  * to yield significantly better space and time performance by 
    590  * caching frequently requested values. 
    591  * 
    592  * @param i an {@code int} value. 
    593  * @return an {@code Integer} instance representing {@code i}. 
    594  * @since 1.5 
    595  */ 
    596  public static Integer valueOf(int i) { 
    597   final int offset = 128; 
    598   if (i >= -128 && i <= 127) { // must cache 
    599    return IntegerCache.cache[i + offset]; 
    600   } 
    601   return new Integer(i); 
    602  } 
+2

您還必須知道'Integer i = x'在內部編譯爲'Integer.valueOf(x)',它是。 – 2010-03-23 13:08:34

+0

謝謝,感覺有些失蹤。 – Tom 2010-03-23 13:11:12