Java 將某些基本數據類型自動轉換為包裝類型的過程稱為裝箱,相反自動將包裝類型轉換為基本數據類型的過程稱為拆箱。
Integer integer_1=1; //裝箱
int i=integer_1; //拆箱
裝箱會調用 Integer.valueOf(int) 函數:
拆箱會調用 Integer.intValue(Integer) 函數
幾個面試中會經常遇到的問題:
先來看一段代碼:
這段代碼的輸出結果是:
對於第一行和第二行,因為裝箱會調用vlueOf(),我們來看看這個函數的源碼:
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); }
IntegerCach的源碼是:
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) { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low)); } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); } private IntegerCache() {} }
從源碼可以看出來這個函數內部是怎麼處理裝箱的,如果這個int值在-128-127之間,會返回一個已經定義好了的數組裡面的元素,所以第一行是 true ,第二行是 false。
這裡需要注意的是:除開浮點型的數值,Double和Float,其余的類型(當然包括Boolean類型)均是類似的操作,因為Double和Float的數值個數是無法統計的。如下:
Double double_1=27.0; Double double_2=27.0;
System.out.println(double_1==double_2);
可能開始你會想結果是true,其實結果是false:
對於第三行,和第四行,如果==有一邊存在算術表達式,則會拆箱,所以第3,4行均為true。
對於第5行,equals函數不會改變對象類型,所以類型不一樣們自然是false。
另一個問題:
Integer i=new Integer(1); 和 Integer i=1又和區別?
前者不會觸發裝箱,後者會觸發裝箱,性能上和執行效率上,後者一般更優,但不是絕對的。