2013-03-06 80 views
5

我無法理解obj和obj2對象在以下代碼中創建方式的差異。特別是,我不確定一個基元如何投射到一個物體上。看看這裏的其他一些問題,我認爲這是不可能的。但下面的程序編譯並運行良好。在第一種情況下,輸出是錯誤的,在第二種情況下是真的。== Java中對象的運算符

public class Test { 

    public static void main(String args[]){ 

     Integer num = new Integer(3) ; 
     Object obj = num; 
     Integer[] integerArr = {1, 2, 3, 4}; 
     Object[] objArr = integerArr; 
     boolean contains = false; 

     for (int i = 0; i < objArr.length; i++){ 
      if (objArr[i] == obj){ 
       contains = true; 
       break; 
      } 
     } 

     System.out.println(contains); 

     int num2 = 3 ; 
     Object obj2 = num2; 
     Integer[] integerArr2 = {1, 2, 3, 4}; 
     Object[] objArr2 = integerArr2; 
     boolean contains2 = false; 

     for (int i = 0; i < objArr2.length; i++){ 
      if (objArr2[i] == obj2){ 
       contains2 = true; 
       break; 
      } 
     } 

     System.out.println(contains2); 
    } 

} 
+4

你很幸運。整數對象被緩存爲小值。 – Mysticial 2013-03-06 00:31:54

+0

@Mystical:謝謝 – 2013-03-06 00:37:00

+1

重複,重複,重複..現在就找到它們。 – 2013-03-06 00:40:08

回答

3

你必須從java.lang.Integer

public static Integer valueOf(int i) { 
    assert IntegerCache.high >= 127; 
    if (i >= IntegerCache.low && i <= IntegerCache.high) 
     return IntegerCache.cache[i + (-IntegerCache.low)]; 
    return new Integer(i); 
} 

理解這種方法在第一種情況下,你創建一個新的Integer對象,而在第二種情況下,編譯器並轉換爲你使用緩存。

/** 
* Cache to support the object identity semantics of autoboxing for values between 
* -128 and 127 (inclusive) as required by JLS. 
* 
* The cache is initialized on first usage. The size of the cache 
* may be controlled by the -XX:AutoBoxCacheMax=<size> option. 
* During VM initialization, java.lang.Integer.IntegerCache.high property 
* may be set and saved in the private system properties in the 
* sun.misc.VM class. 
*/ 

下面是相關的字節碼,看它如何結束調用的Integer構造函數或Integer.valueOf

0: new #2; //class java/lang/Integer 
3: dup 
4: iconst_3 
5: invokespecial #3; //Method java/lang/Integer."<init>":(I)V 
8: astore_1 
9: aload_1 
10: astore_2 
11: iconst_4 
12: anewarray #2; //class java/lang/Integer 
15: dup 
16: iconst_0 
17: iconst_1 
18: invokestatiC#4; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 
21: aastore 
... 
90: iconst_3 
91: istore 6 
93: iload 6 
95: invokestatiC#4; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 
98: astore 7 
100: iconst_4 
101: anewarray #2; //class java/lang/Integer 
104: dup 
105: iconst_0 
106: iconst_1 
107: invokestatiC#4; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 
110: aastore 
111: dup 
... 
+0

感謝您澄清@ Mysticial的評論。這是我正在尋找的。 – 2013-03-06 00:37:30

4

對象測試之間的==操作者爲身份(如果兩個對象是完全一樣的),而對於平等(兩個對象是否具有相同的值)的方法equals()測試。

大多數時候,你會對平等感興趣。一次偶然的機會,比如你的問題提供實際工作,因爲Integer對象緩存(通常在-127到127的範圍內,雖然這是可配置的),但是如果你測試使用一個更大的數字身份,它很可能測試將失敗。

例如,這將評估爲true

Integer a = 127; 
Integer b = 127; 
a == b // true 

而這將評估爲false

Integer a = 128; 
Integer b = 128; 
a == b // false 

底線:發揮它的安全性,總是使用equals()來測試對象之間的相等性。

+1

謝謝。我知道關於equals方法,我也使用它,但我只是好奇爲什麼==在上述情況之一工作。 – 2013-03-06 00:35:29

0

在第二種情況下,你要比較原始int到對象Integer數組。 JVM正在「展開」對象Integer並與原始對象進行比較..因此,在這種情況下您確實會得到相等匹配。

在第一種情況下,你總是比較的對象與另一個對象,並在你的榜樣,這些永遠不會相等。

1

==如果object1和object2是引用類型,則==檢查object1和object2是否都是對同一對象的引用。

如果使用object1等於。等於(Object2的),則它比較對象

實施例的實際值:

使用String.equals(字符串等)函數來比較字符串,而不是==運算符。

函數檢查字符串的實際內容,==運算符檢查對象的引用是否相等。