簡體   English   中英

Java的==上的行為不一致

[英]Inconsistent behavior on java's ==

考慮以下代碼:

class test {
   public static void main(String[] args) {
      test inst_test = new test();
      int i1 = 2000;
      int i2 = 2000;
      int i3 = 2;
      int i4 = 2;
      Integer Ithree = new Integer(2); // 1
      Integer Ifour = new Integer(2); // 2
      System.out.println( Ithree == Ifour );
      inst_test.method( i3 , i4 );
      inst_test.method( i1 , i2 );
   }
   public void method( Integer i , Integer eye ) {
      System.out.println(i == eye );
   }
}

它打印:

false
true
false

我知道第一個false ,==運算符僅檢查兩個引用是否在同一個對象上工作,在這種情況下不是。

以下truefalse讓我撓頭。 Java為什么會認為i3i4相等但i1i2不同? 兩者都包裝在Integer中,難道都不應該為假? 是否存在這種不一致的實際原因?

將原語自動裝箱到對象中(在對method的調用中使用的是使用小的值的緩存。請參見Java語言規范第5.1.7節

如果要裝箱的值p為true,false,一個字節,介於\\ u0000到\\ u007f之間的char或-128和127之間的int或short數字,則令r1和r2為任何兩次裝箱轉換的結果的p。 r1 == r2總是這樣。

緊隨其后的規范討論部分也很有趣。 值得注意的是,JVM可以根據需要緩存更多的值-您不能確定這樣做的結果:

Integer i1 = 129;
Integer i2 = 129;
boolean b = (i1 == i2);

自動裝箱時,將緩存-128和127之間的整數,並返回相同的包裝對象。 \\ u0000和\\ u007F之間的布爾值和char值相同

這是您大部分時間所獲得的,但是它取決於JVM的實現。

這是因為裝箱會使低於某個值(我認為是128)的整數引用某些預先構造的對象,而將更高的值引用到新對象。

自動裝箱使用Integer.valueOf(i)而非新的Integer(i)來構造Integer類的對象。

正如其他人所說,valueOf()使用緩存,主要是為了提高空間效率。

不要在引用類型上使用==,這幾乎總是一個錯誤。

我猜想包裝會盡量減少Integer對象的數量,並只創建一個代表2個對象的對象,這也可以節省內存。

只要記住永遠不要在對象上使用==,就永遠不知道會發生什么。

整數類包含一些常用實例的緩存。 值的范圍通常因JVM而異(有時也是可配置的),但總的來說,相關代碼如下:

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

(來自sun JDK 1.6的代碼)

這就像字符串實習,因為它既節省了內存,又允許使用引用進行測試相等(例如==代替equals

自動裝箱使用某些緩存機制。 通常,您永遠不要依賴== ,始終使用equals來檢查相等性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM