1.介紹
關於Integer和int在面試的時候出現的頻率很高。而我們所熟知的是Integer是int 的封裝類型,int的初始值為0,Integer的初始值為null,這是基本都知道的。至於Integer的自動裝箱和拆箱,以及Integer的緩衝等小細節需要深入思考。 2.封裝類的裝箱和拆箱
從基礎資料型別 (Elementary Data Type)到封裝類型的過程是裝箱、從封裝類型到基礎資料型別 (Elementary Data Type)的過程是拆箱。
例子:
public static void main(String[] args) {//標準的裝箱過程Integer i =new Integer(127);/** * 這個寫法相當於Integer i1 =new Integer(127); * 這個初始化的過程預設也是使用了自動裝箱 * 裝箱的本意就是將基礎資料型別 (Elementary Data Type)轉換成封裝類型 * */Integer i1 =127;//標準的拆箱過程int j =i.intValue();/** * 這個寫法相當於int j1 =i1.intValue(); * 這個初始化的過程預設也是使用了自動拆箱過程 * 拆箱的本意就是將封裝類型轉換成基礎資料型別 (Elementary Data Type) * */int j1 =i1;}
| int(4位元組) |
Integer |
| byte(1位元組) |
Byte |
| short(2位元組) |
Short |
| long(8位元組) |
Long |
| float(4位元組) |
Float |
| double(8位元組) |
Double |
| char(2位元組) |
Character |
| boolean(未定) |
Boolean |
3.Integer的緩衝
Integer定義了一個靜態內部類IntegerCache作為緩衝
緩衝源碼:
private static class IntegerCache {//常量最小值-128 static final int low = -128;//常量最大值 static final int high;//Integer緩衝數組 static final Integer cache[]; static { //初始化h變數為127 int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { int i = parseInt(integerCacheHighPropValue);//說明i最小可以取到127,規定了i的下限,所以i>=127 i = Math.max(i, 127);//由於i>=127並且Integer.MAX_VALUE - (-low)>128,因此可以得到h>=127 h = Math.min(i, Integer.MAX_VALUE - (-low)); } high = h;//初始化Integer緩衝數組 cache = new Integer[(high - low) + 1];//數組中的初始值是-128 int j = low;//迴圈為數組賦值,數組0位是-128,最大是127(臨界值) for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); } private IntegerCache() {}}/** * 返回一個表示指定的 int 值的 Integer 執行個體。 * 如果不需要新的 Integer 執行個體,則通常應優先使用該方法,而不是構造方法 Integer(int) * 因為該方法有可能通過緩衝經常請求的值而顯著提高空間和時間效能 */public static Integer valueOf(int i) { assert IntegerCache.high >= 127; //當-128<=i<=127時,直接從緩衝數組中取出值 if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; //否則返回新的Integer對象 return new Integer(i);} 而我們使用Integer i=100的時候採取的裝箱操作實際上調用了valueof方法,API也提示盡量多使用valueof的方式建立Integer的執行個體而不是以new Integer的方式。因為valueof方式使用緩衝提高空間的利用率和時間效能。
4.經典面試題
public static void main(String[] args) {//標準的裝箱過程Integer i =new Integer(100);Integer i1 =100;Integer i2 =100;Integer i3 =128;Integer i4 =128;System.out.println("i==i1 :"+(i==i1));System.out.println("i1==i2 :"+(i1==i2));System.out.println("i3==i4 :"+(i3==i4)); } 列印結果:
解釋:
(1) i == i1 :由於i本身是new Integer的方式單獨開闢空間,i1是 -128<=i1<=127,所以i1是從緩衝中取出資料的。而緩衝的地址和new Integer單獨開闢空間對應的地址不同,返回false。
(2) i1 == i2 :i1是 -128<=i1<=127,所以i1是從緩衝中取出資料的。i2是-128<=i2<=127,所以i2也是從緩衝中取出資料的。所以i1和i2對應的是同一個緩衝地址,返回true。
(3)i3 == i4 :i3>127並且i4>127,所以i3和i4分別是new Integer這種單獨開闢空間,地址不同,返回false。