一.integer包裝類
先看個小例子
Integer i1 = 25;
Integer i2 = 25;
Integer i21 = Integer.valueOf(25);
Integer i22 = new Integer(25);
Integer i3 = 128;
Integer i4 = 128;
System.out.println(i1 == i2); //true
System.out.println(i1 == i21); //true
System.out.println(i1 == i22); //false
System.out.println(i3 == i4); //false
看到結果,why?我們知道==比較是否指向相同的對象,本質是棧內局部變量表中reference存儲的值是否相等,對于基本類型存儲的是數據值,對于引用類型(接口,類,數組)存儲的是堆中對象的地址。
1.Integer i22 = new Integer(25); 毫無疑問是在堆中創建一個新對象;
2.Integer i1 = 25;我們知道會觸發自動裝箱操作,也就是調用valueOf()來創建Integer 對象,為何相同呢?因為在類加載時內部類IntegerCache中的靜態塊已經把部分(默認是-128~127)Integer對象初始化好緩存起來了static final Integer cache[];
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"); --可配置
...
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
so,Integer i1 = 25; 和 Integer.valueOf(25);直接來這個cache[]讀取共享復用就行了。
- Integer i3 = 128; Integer i4 = 128; 超出了high位,需要自行創建新對象。
二. String享元模式和包裝類型區別
Integer 類中要共享的對象,是在類加載的時候,就集中一次性創建好的。
但是,對于字符串來說,我們沒法事先知道要共享哪些字符串常量,所以沒辦法事先創建好,只能在某個字符串常量第一次被用到的時候,存儲到常量池中,當之后再用到的時候,直接引用常量池中已經存在的即可,就不需要再重新創建了。