自動裝箱、拆箱

吃桃子的小松鼠發表於2019-03-04

java中有8種基本資料型別,byte、short、char、int、long、boolean、double、float,在一些資料結構中,是不支援基本資料型別,所以java巨人們又搞出一些基本資料型別的裝箱型別Byte、Short、Char、Integer Long Boolean Double Float

看下面的程式碼例子:

Integer num = 100;
int i = num;//拆箱
int i2 = 100;
Integer num2 = i2; //裝箱

實際上 底層原理 在裝箱的時候是調的  Integer類的 value0f()函式方法,拆箱調的是intValue()方法;既然瞭解了裝箱和拆箱的 底層呼叫原理,那麼我們就測試幾種情況

Integer num = 100;

int i = 100;

Integer num2 = 100;

int i2 = 128

Integer num3=128;

Integer num4 = 128;

System.out.prinlt(num==i);// true

System.out.prinlt(num==num2);//true

System.out.prinlt(num3==i2);//true

System.out.prinlt(num3==num4);//false

從輸出結果可以知道,在裝箱、拆箱中 基本資料型別和 Integer型別的數值比較 總是相等,因為==對於基本型別 就是比較值

但是,當同樣是Integer型別的 時候, 第二行輸出的結果和 第四行輸出的結果確相反,既然都是呼叫的Integer的valueOf方法,為什麼輸出確相反那,那我們就去看一下Integer的原始碼

public static Integer valueOf(int i) {
   if (i >= IntegerCache.low && i <= IntegerCache.high)
    return IntegerCache.cache[i + (-IntegerCache.low)];
  return new Integer(i);
}

從valueOf 方法的判斷可以看出, 當i不在一個約定的範圍之內的時候, 就會new一個新物件,那我們在首先看一下 這個範圍是什麼

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() {}
}

 

從標黑加粗的可以看出, 這個範圍就是-128, 127],意思就是在-128和127 範圍內,不會去 new一個新物件,那麼會從哪取的物件那,我們可以深入進入程式碼看一下

 if (i >= 128 && i <= -127)
    return IntegerCache.cache[i + (-IntegerCache.low)];

可以看去是從IntegerCache(靜態內部類)的一個方法中取出來的,看上面標紅的程式碼。可以看出,cache 初始化一個127+128+1=256的一個長度的陣列,然後往這個陣列中初始化物件,這樣 當載入Integer的時候,就會載入靜態程式碼塊,載入出 一個長度為256的陣列,裡面是包含-128 到 127的物件,所以在範圍內,就會直接在陣列中取出相應的物件,不會建立新的物件。

 

第一次在部落格園寫部落格,後續我會持續下去,吧自己學到的,遇到的坑,都會總結出來。

相關文章