关于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集合填充完成
相关文章
相关标签/搜索