2010-07-28 51 views
16
public class Main { 
    /** 
     * @param args the command line arguments */ 
    public static void main(String[] args) { 
     // TODO code application logic here 
     int a1 = 1000, a2 = 1000; 
     System.out.println(a1==a2);//=>true 
     Integer b1 = 1000, b2 = 1000; 
     System.out.println(b1 == b2);//=>false 
     Integer c1 = 100, c2 = 100; 
     System.out.println(c1 == c2);//=>true 
    } 

} 

爲什麼b1 == b2爲false並且c1 == c2爲true?有關自動裝箱和對象相等/標識的Java問題

回答

0

你想要的答案是here

2

您可以在這裏找到答案:

在6回答Strangest language feature

編輯:對不起,沒有很好的答案。重點是==比較引用,而不是與Integer一起使用時的值。但用int「==」表示等於。

36

閱讀this

Java應用Integer S IN的範圍從-128到127

,如果你創建一個IntegerInteger i = 42;,其值爲-128和128之間這意味着,沒有新對象已創建,但會返回池中相應的一個。這就是爲什麼c1確實是相同c2

我假設你知道==比較引用,而不是值,當應用於對象)。

+0

非常感謝Felix Kling。我明白這個代碼 – OOP 2010-07-28 11:03:59

+0

這並不能解釋爲什麼a1 == a2。 – simon 2010-07-28 12:56:02

+1

如果我沒有弄錯,問題是關於'b1 == b2'和'c1 == c2'。 – 2010-07-28 13:07:16

2

因爲整數是像枚舉一樣的低數字,所以總是有相同的實例。但更高的數字會創建Integer和運算符的新實例==比較它們的引用

11

已經給出了正確的答案。但只是添加我的兩分錢:

Integer b1 = 1000, b2 = 1000; 

這是可怕的代碼。對象應通過構造函數或工廠方法初始化爲對象。例如。

// let java decide if a new object must be created or one is taken from the pool 
Integer b1 = Integer.valueOf(1000); 

// always use a new object 
Integer b2 = new Integer(1000); 

在另一方面該代碼

Integer b1 = 1000, b2 = 1000; 

意味着整數是一個原始的,它是沒有的。其實你看到的是

Integer b1 = Integer.valueOf(1000), b2 = Integer.valueOf(1000); 

和Integer只有池對象從-127到127的快捷方式,所以它會建立在這種情況下,兩個新的對象。所以儘管1000 = 1000,b1!= b2。這是我討厭自動拳擊的主要原因。

+0

非常感謝seanizer! – OOP 2010-07-28 11:03:03

+0

爲什麼downvote? – 2011-03-06 19:29:27

2
public static Integer valueOf(int i) { 
     final int offset = 128; 
     if (i >= -128 && i <= 127) { // must cache 
      return IntegerCache.cache[i + offset]; 
     } 
     return new Integer(i); 
    } 

正因爲如此,你在一種情況下是正確的,而在其他情況下是錯誤的!

+0

+1來源的報價。也是正確範圍的第一個答案! – 2013-01-16 14:20:05

0

如果autounboxing也努力做平等的「==」操作檢查時,你可以寫:

Long notNullSafeLong1 = new Long(11L) 
    Long notNullSafeLong2 = new Long(22L) 
    if (notNullSafeLong1 == notNullSafeLong2) { 
     do suff 

這將需要實施一個覆蓋了==使空== someLong是假的和特例Null == Null爲真。相反,我們必須使用等於()和測試空

Long notNullSafeLong1 = new Long(11L) 
    Long notNullSafeLong2 = new Long(22L) 
    if ((notNullSafeLong1 == null && notNullSafeLong2 == null) || 
     (notNullSafeLong1 != null && notNullSafeLong2 != null & 
     notNullSafeLong1.equals(notNullSafeLong2)) { 
     do suff  

這比第一個例子小有一點更詳細的 - 如果autounboxing曾經爲「==」操作員的工作。