天天看點

java整形包裝類自動拆箱範圍_Java(47):解剖 Integer 等包裝類的自動裝箱拆箱和jvm緩存機制...

目錄

寫在開頭

自動裝箱和拆箱、for循環都是java語言的文法糖!!

《深入了解JVM虛拟機》

Integer包裝類的緩存機制

Integer的緩存機制: Integer是對小資料(-128~127)是有緩存的,再jvm初始化的時候,資料-128~127之間的數字便被緩存到了本地記憶體中,如果初始化-128~127之間的數字,會直接從記憶體中取出,不需要建立一個對象。

這種 Integer 緩存政策僅在自動裝箱(autoboxing)的時候有用,使用構造器建立的 Integer 對象不能被緩存。

IntegerCache,Javadoc 詳細的說明這個類是用來實作緩存支援,并支援 -128 到 127 之間的自動裝箱過程。最大值 127 可以通過 JVM 的啟動參數 -XX:AutoBoxCacheMax=size 修改。

緩存通過一個 for 循環實作。從小到大的建立盡可能多的整數并存儲在一個名為 cache 的整數數組中。這個緩存會在 Integer 類第一次被使用的時候被初始化出來。以後,就可以使用緩存中包含的執行個體對象,而不是建立一個新的執行個體(在自動裝箱的情況下)。

緩存機制,本質上通過靜态内部類,實作懶加載,for循環設定内部類的數組範圍。

Integer源碼(節選)

public static Integer valueOf(int i) {

if (i >= IntegerCache.low && i <= IntegerCache.high)

return IntegerCache.cache[i + (-IntegerCache.low)];

return new Integer(i);

}

//靜态内部類

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對象。我們針對所有整數類型的類都有類似的緩存機制。

有 CharacterCache 用于緩存 Character 對象,緩存範圍是[0,127]

有 ByteCache 用于緩存 Byte 對象,緩存範圍是[-128,127]

有 ShortCache 用于緩存 Short 對象,緩存範圍是[-128,127]

有 LongCache 用于緩存 Long 對象,緩存範圍是[-128,127]

除了 Integer 可以通過參數改變範圍外,其它的都不行。修改虛拟機的Integer緩存最大值。

自動裝箱

java的文法糖之一,8種基本類型對應8種包裝類。Java 編譯器把原始類型自動轉換為封裝類的過程稱為自動裝箱(autoboxing),這相當于調用 valueOf 方法。

基本資料類型

包裝類

byte

Byte

short

Short

int

Integer

long

Long

char

Character

float

Float

double

Double

boolean

Boolean

Integer初始化的三種方式

Integer a = 10; //this is autoboxing,自動裝箱,等價于Integer.valueOf()

Integer b = Integer.valueOf(10); //under the hood,使用緩存機制

Integer num1 = new Integer(100);//建立新的操作對象

比較運算符的應用

==:java中的==是用于判斷兩個操作數是否相等的,如果操作數是基本資料類型,則判斷值是否相等;如果操作數是對象,則判斷兩個對象的位址是否相等(也就是引用是否相等),是以,這裡就很明确了,num1 和num2是兩個對象,自然位址是不一樣的。

equals:值比較同資料類型的兩個對象的資料值。

參考文章: