JAVA整数类型包装类的缓存策略

Java Integer的缓存策略

public class JavaIntegerCache {
    public static void main(String... strings) {
 
        Integer integer1 = 3;
        Integer integer2 = 3;
 
        if (integer1 == integer2)
            System.out.println("integer1 == integer2");
        else
            System.out.println("integer1 != integer2");
 
        Integer integer3 = 300;
        Integer integer4 = 300;
 
        if (integer3 == integer4)
            System.out.println("integer3 == integer4");
        else
            System.out.println("integer3 != integer4");
 
    }
}

== 比较的是对象引用,而 equals 比较的是值。所以,在这个例子中,不一样的对象有不一样的引用,因此在进行比较的时候都应该返回 false。可是奇怪的是,这里两个类似的 if 条件判断却返回不一样的布尔值。java

输出结果:数组

integer1 == integer2
integer3 != integer4

Java 中 Integer 缓存实现:

在 Java 5 中,为 Integer 的操做引入了一个新的特性,用来节省内存和提升性能。整型对象在内部实现中经过使用相同的对象引用实现了缓存和重用。缓存

上面的规则适用于整数区间 -128 到 +127。性能

这种 Integer 缓存策略仅在自动装箱(autoboxing)的时候有用,使用构造器建立的 Integer 对象不能被缓存spa

Java 编译器把原始类型自动转换为封装类的过程称为自动装箱(autoboxing),这至关于调用 valueOf 方法code

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

在建立新的 Integer 对象以前会先在 IntegerCache.cache 中查找。IntegerCache 类专门来负责 Integer 的缓存。orm

IntegerCache 是 Integer 类中一个私有的静态类(Integer的嵌套类)对象

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() {}
    }

  这个类是用来实现缓存支持,并支持 -128 到 127 之间的自动装箱过程。最大值 127 能够经过 JVM 的启动参数 -XX:AutoBoxCacheMax=size 修改缓存经过一个 for 循环实现。从小到大的建立尽量多的整数并存储在一个名为 cache 的整数数组中。这个缓存会在 Integer 类第一次被使用的时候被初始化出来。之后,就可使用缓存中包含的实例对象,而不是建立一个新的实例(在自动装箱的状况下)。blog

  实际上在 Java 5 中引入这个特性的时候,范围是固定的 -128 至 +127。后来在 Java 6 中,最大值映射到 java.lang.Integer.IntegerCache.high,可使用 JVM 的启动参数设置最大值。选择这个 -128 到 127 这个范围,是由于这个范围的整数值是使用最普遍的。 在程序中第一次使用 Integer 的时候也须要必定的额外时间来初始化这个缓存。内存

 

其余缓存的对象

这种缓存行为不只适用于Integer对象。咱们针对全部整数类型的类都有相似的缓存机制。

有 ByteCache 用于缓存 Byte 对象

有 ShortCache 用于缓存 Short 对象

有 LongCache 用于缓存 Long 对象

有 CharacterCache 用于缓存 Character 对象

Byte,Short,Long 有固定范围: -128 到 127。对于 Character, 范围是 0 到 127。除了 Integer 能够经过参数改变范围外,其它的都不行。

相关文章
相关标签/搜索