[英]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
,==運算符僅檢查兩個引用是否在同一個對象上工作,在這種情況下不是。
以下true
與false
讓我撓頭。 Java為什么會認為i3
和i4
相等但i1
和i2
不同? 兩者都包裝在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.