Integer緩存機制java
總結:面試
一、jdk1.5對Integer新增了緩存機制,範圍在-128-127(這個範圍的整數值使用頻率最高)內的自動裝箱返回的是緩存對象,不會new新的對象,因此只要在緩存範圍內值相等自動裝箱返回的對象同樣。jdk1.6後緩存範圍的最大值127能夠經過設置jvm的啓動參數(-XX:AutoBoxCacheMax=size)調整
二、Integer的緩存只在自動裝箱時有效,使用構造器(new)建立的對象不會觸發緩存
三、int和Integer比較時不用考慮緩存問題,由於Integer會自動拆箱爲int再和int比較,這時只是單純的比較值是否相等數組
詳解:
針對Integer常見的一個面試題爲緩存
Integer i1 = 100; Integer i2 = 100; Integer j1 = 200; Integer j2 = 200; System.out.println(i1 == i2); // 輸出 true System.out.println(j1 == j2); // 輸出 false
咱們對於Integer最基本的理解是Integer是int的包裝類,是引用數據類型,引用數據類型用==比較的是對象的內存地址。
咱們來看i1的建立過程(jdk1.8)
首先會對Integer i1 = 100;自動裝箱(其實就是調用valueOf方法),java會把這段編譯爲Integer i1 = Integer.valueOf(100),能夠自行查看class文件驗證。
而後再看Integer.valueOf方法:jvm
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
能夠清楚的看到是先從IntegerCache取值,IntegerCache.low IntegerCache.high 範圍外則直接new對象(new的對象會存在堆內存中)ide
咱們再來看IntegerCache類,IntegerCache爲Integer的私有靜態類ui
1 /** 2 * Cache to support the object identity semantics of autoboxing for values between 3 * -128 and 127 (inclusive) as required by JLS. 4 * 5 * The cache is initialized on first usage. The size of the cache 第一次使用時生效 6 * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option. 可經過參數設置最大值 7 * During VM initialization, java.lang.Integer.IntegerCache.high property 8 * may be set and saved in the private system properties in the 9 * sun.misc.VM class. 10 */ 11 12 private static class IntegerCache { 13 static final int low = -128; 14 static final int high; 15 static final Integer cache[]; 16 17 static { 18 // high value may be configured by property 19 int h = 127; 20 String integerCacheHighPropValue = 21 sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); 22 if (integerCacheHighPropValue != null) { 23 try { 24 int i = parseInt(integerCacheHighPropValue); 25 i = Math.max(i, 127); 26 // Maximum array size is Integer.MAX_VALUE 27 h = Math.min(i, Integer.MAX_VALUE - (-low) -1); 28 } catch( NumberFormatException nfe) { 29 // If the property cannot be parsed into an int, ignore it. 30 } 31 } 32 high = h; 33 34 cache = new Integer[(high - low) + 1]; 35 int j = low; 36 for(int k = 0; k < cache.length; k++) 37 cache[k] = new Integer(j++); 38 39 // range [-128, 127] must be interned (JLS7 5.1.7) 40 assert IntegerCache.high >= 127; 41 } 42 43 private IntegerCache() {} 44 }
Integer的緩存經過for循環建立存放到一個數組中,註釋已經解釋該數組會在Integer第一次使用時初始化,結合類加載順序來理解,第一次使用Integer時內部靜態類會被初始化,靜態代碼塊會被執行,存到堆中。會有第一次懲罰spa
jdk1.5源碼參考.net
1 private static class IntegerCache { 2 static final Integer[] cache = new Integer[256]; 3 4 static { 5 for (int i = 0; i < cache.length; i++) { 6 cache[i] = new Integer(i - 128); 7 } 8 } 9 } 10 11 public static Integer valueOf(int paramInt) { 12 if ((paramInt >= -128) && (paramInt <= 127)) { 13 return IntegerCache.cache[(paramInt + 128)]; 14 } 15 return new Integer(paramInt); 16 }
Integer與int用==比較時Integer會自動拆箱(調用intValue()方法)爲int進行比較
i1 == 100 會編譯成 i1.intValue() == 100code
其餘緩存的對象
這種緩存行爲不只適用於Integer對象。咱們針對全部整數類型的類都有相似的緩存機制。
有 ByteCache 用於緩存 Byte 對象
有 ShortCache 用於緩存 Short 對象
有 LongCache 用於緩存 Long 對象
有 CharacterCache 用於緩存 Character 對象
Byte,Short,Long 有固定範圍: -128 到 127。對於 Character, 範圍是 0 到 127。除了 Integer 能夠經過參數改變範圍外,其它的都不行。
參考博文:https://blog.csdn.net/qq_27093465/article/details/52473649
int與Integer(基本類型與包裝類型)
Integer是int的包裝類型,二者的區別爲:
一、int初始值爲0,Integer初始值爲null,全部的引用類型都爲null;
二、Integer爲引用類型,對象存放在堆中。int爲基本數據類型,對象存放在棧中;
使用包裝類的好處:
一、Integer封裝了不少處理方法,方便操做,好比進制轉化(toBinaryString)、數據類型之間的轉化(toString);
二、解決有些類型不支持基礎數據類型的狀況,好比List只能接收引用類型;
至於什麼時候使用基本數據類型,什麼時候使用包裝類型這個就要看具體需求,當只是做爲數值不須要更多的操做時用基本類型就可,靈活使用
基本數據類型和對應的包裝類
int——Integer
float——Float
double——Double
byte——Byte
long——Long
char——Character
boolean——Boolean
short——Short
自動拆裝箱(jdk1.5引入)
自動拆箱實際上就是引用類型自動轉化成基本數據類型,自動裝箱實際上就是基本數據類型自動轉化成對應的引用類型
好比建立Integer i = new Integer(100); 能夠直接寫成Integer i = 100;不須要強轉 (自動裝箱)
int j = i 基本數據類型j能夠直接等於引用類型i (自動拆箱)
1 Integer i = 1; 2 int j = i; 3 4 /** 5 * 上面代碼編譯成class後 6 */ 7 Integer i = Integer.valueOf(1); 8 int j = i.intValue();
由上能夠看出自動裝箱實際上就是調用了valueOf方法,自動拆箱調用了intValue方法