java中Integer與int比較淺談
阿新 • • 發佈:2019-02-17
今天看到一個面試題
測試程式碼如下
public class test {
@Test
public void test(){
Integer a = 300 ;
Integer b = 300;
int c = 300;
System.out.println(a == b);
System.out.println(a == c);
Integer int1 = 100;
Integer int2 = 100;
System.out.println(int1 == int2);
}
}
輸出結果
false
true
true
Process finished with exit code 0
300難道不等於300麼。結果為什麼會這樣呢?
先反編譯看一波
public class test {
public test() {
}
@Test
public void test() {
Integer a = Integer.valueOf(300);
Integer b = Integer.valueOf(300);
int c = 300;
System.out.println(a == b);
System.out.println(a.intValue() == c);
Integer int1 = Integer.valueOf("100");
Integer int2 = Integer.valueOf("100");
System.out.println(int1 == int2);
}
}
可見,通過 Integer a = 300;這種方法新建一個Integer實際上是呼叫 Integer.valueOf();的方法建立了一個Integer物件,那為什麼a == b結果為false呢,我門繼續看Integer.valueOf();的原始碼
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
這裡冒出來一個IntegerCache類,我們繼續看原始碼
IntegerCache 是 Integer的一個私有靜態內部類,繼續看
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
從高亮部分程式碼我們可以看出
原來Integer把-128到127(可調)的整數都提前例項化了,但是為什麼JDK要這麼多此一舉呢? 我們仔細想想, 淘寶的商品大多數都是100以內的價格, 一天後臺伺服器會new多少個這個的Integer, 用了IntegerCache,就減少了new的時間也就提升了效率。同時JDK還提供cache中high值得可配置,這無疑提高了靈活性,方便對JVM進行優化。
好了現在回來看出現3個問題
1.
Integer a = 300;
Integer b = 300;
System.out.println(a == b);
結果:false
原因 : 在建立a,b的時候實際上會呼叫Integer.valueOf();方法,在Integer.valueOf()方法中,範圍在-128~127的都已經被提前例項化了,而我們這裡的值為300,並沒有被提前例項化,所以會new 一個新的Integer,而“==”是對地址的比較,a與b是分別new出來的,所有地址顯然不一樣,結果為false
2.
Integer int1 = 100;
Integer int2 = 100;
System.out.println(int1 == int2);
結果:true
有上面的基礎這裡就比較好理解了,因為Integer的-128~127都提前被例項化了,而100在這個範圍之內,所以int1和int2實際指向記憶體同一塊地址,故結果為true
3.
Integer a = 300 ;
int c = 300;
System.out.println(a == c);
結果 : false
這個從反編譯的結果看來就很簡單了,在jdk1.5後有了自動拆箱機制,a == c 實際上就是a.intValue() == c ,300 當然等於300所有結果為true