Integer缓冲池IntegerCache

缓冲池IntegerCache

Integer中有个静态内部类IntegerCache,里面有个cache[],也就是Integer常量池,常量池的大小为一个字节(-128~127)。

源码为(jdk1.8.0_101)

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");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    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++);
            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }
        private IntegerCache() {}
    }

当创建Integer对象时,不使用new Integer(int i)语句,大小在-128~127之间,对象存放在Integer常量池中。

例如:Integer a = 10;

调用的是Integer.valueOf()方法,代码为

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

这也是自动装箱的代码实现。

测试Integer的特性:

public class TestInteger {
    public static void main(String[] args) {
        //jdk1.5后 虚拟机为包装类提供了缓冲池,Integer缓冲池的大小为一个字节(-128~127); 
        //创建  1 个对象,存放在常量池中。引用c1,c2存放在栈内存中。
        Integer c1 = 1;
        Integer c2 = 1;
        System.out.println("c1 = c2 ? " + (c1 == c2)); //true

        //创建 2  个对象,存放在堆内存中。2 个引用存放在栈内存中。
        Integer b1 = 130; //130不在(-128~127)之间
        Integer b2 = 130;
        System.out.println("b1 = b2 ? " + (b1 == b2)); //false

        //创建2个对象,存放在堆内存中。
        Integer b3 = new Integer(2);
        Integer b4 = new Integer(2);
        System.out.println("b3 = b4 ? " + (b3 == b4));  //false
        //下面两行代码证明了使用new Integer(int i) (i 在-128~127之间)创建对象不会保存在常量池中。
        Integer b5 = 2;
        System.out.println("b3 = b5 ? " + (b3 == b5));  //false

        //Integer的自动拆箱,b3自动转换成数字 2。
        System.out.println("b3 = 2 ? " + (b3 == 2));   //true
        Integer b6 = 210;
        System.out.println("b6 = 210 ? " + (b6 == 210));   //true
    }
}

打印结果为:
c1 = c2 ? true
b1 = b2 ? false
b3 = b4 ? false
b3 = b5 ? false
b3 = 2 ? true
b6 = 210 ? true


其他缓存的对象

这种缓存行为不仅适用于Integer对象。我们针对所有整数类型的类都有类似的缓存机制。
有 ByteCache 用于缓存 Byte 对象
有 ShortCache 用于缓存 Short 对象
有 LongCache 用于缓存 Long 对象
有 CharacterCache 用于缓存 Character 对象
Byte,Short,Long 有固定范围: -128 到 127。对于 Character, 范围是 0 到 127。除了 Integer 可以通过参数改变范围外,其它的都不行。

建议:所有相同类型的包装类对象之间值得比较,全部使用equals方法。


参考链接

  1. https://www.cnblogs.com/timecloud/p/6555360.html
  2. https://blog.csdn.net/qq_27093465/article/details/52473649

猜你喜欢

转载自blog.csdn.net/so_geili/article/details/79720238