目錄
寫在開頭
自動裝箱和拆箱、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:值比較同資料類型的兩個對象的資料值。
參考文章: