1. 程式人生 > >java中Integer與int比較淺談

java中Integer與int比較淺談

今天看到一個面試題 測試程式碼如下 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