Android
的Surface
看的有點頭暈,換個口味,下一篇再更java
偶然網上看到以下代碼:數組
public class IntegerTest {
private Integer a = 100;
private Integer b = 100;
private Integer c = 200;
private Integer d = 200;
public static void main(String[] args) {
new IntegerTest().test();
}
public void test(){
System.out.println(a==b);
System.out.println(c==d);
}
}
複製代碼
輸出結果以下:緩存
true // 代表 a 和 b 是同一個對象
false // 代表 c 和 d 不是同一個對象
複製代碼
你們可能已經知道這是關於Java
整數對象緩存(-128--127)的問題。markdown
咱們看下到底爲何會這樣spa
class
文件經過javap -c
命令將class
文件進行反彙編,內容以下:code
public class hua.lee.test.IntegerTest {
// 此處是編譯後生成的對象初始化方法
public hua.lee.test.IntegerTest();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: bipush 100
7: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
10: putfield #3 // Field a:Ljava/lang/Integer;
13: aload_0
14: bipush 100
16: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
19: putfield #4 // Field b:Ljava/lang/Integer;
22: aload_0
23: sipush 200
26: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
29: putfield #5 // Field c:Ljava/lang/Integer;
32: aload_0
33: sipush 200
36: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
39: putfield #6 // Field d:Ljava/lang/Integer;
42: return
... // 省略部分
}
複製代碼
以變量a
爲例,它的核心賦值部分是:orm
4: aload_0
5: bipush 100
7: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
10: putfield #3 // Field a:Ljava/lang/Integer;
複製代碼
invokestatic
是執行一個靜態方法的指令,這裏執行的是Integer.valueOf()
,也就是說對象
Java
的自動裝箱其實就是編譯器編譯時將Integer a = 100;
轉換爲Integer a = Integer.valueOf(100);
的操做ip
Integer.valueOf()
Integer.valueOf()
的實現以下:ci
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
複製代碼
能夠看到
IntegerCache.low
和IntegerCache.high
之間的話,會返回IntegerCache.cache
數組中的Integer
對象new Integer()
IntegerCache
是Integer
的內部類,代碼以下:
private static class IntegerCache {
// low 是寫死的
static final int low = -128;
// 關於high,看樣子是能夠動態調整
static final int high;
// 用來緩存 Integer 對象的集合
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
// 從 java.lang.Integer.IntegerCache.high 屬性中讀取緩存的上限
String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
// 屬性不爲空,進行數值轉換處理
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
// 不能小於 127
i = Math.max(i, 127);
// 肯定數組上限
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++);
// assert 保證上限 >= 127
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
複製代碼
關於Integer
的緩存問題咱們就分析完了
Integer
緩存的下限是固定的-128
Integer
緩存的上限能夠經過java.lang.Integer.IntegerCache.high
設置,可是必須>=127
Integer
在類初始化的時候就把緩存集合cahce
建立好了,而且在類初始化時會將cahce
集合填充完成