關於Java中Integer對象緩存問題的分析

AndroidSurface看的有點頭暈,換個口味,下一篇再更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.lowIntegerCache.high之間的話,會返回IntegerCache.cache數組中的Integer對象
  • 不然,new Integer()

IntegerCacheInteger的內部類,代碼以下:

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集合填充完成
相關文章
相關標籤/搜索