Integer緩存機制-基本數據類型和包裝類型-自動拆裝箱

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方法

相關文章
相關標籤/搜索