<导航

Java Integer缓存问题

先看一个问题:

System.out.println(Integer.valueOf(100) == Integer.valueOf(100));
System.out.println(Integer.valueOf(10000) == Integer.valueOf(10000));

结果是:

truefalse
View Code

不是都是new的新对象吗?地址不同,== 不应该是false?

凭空猜测没有意义,看下源码:

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

return IntegerCache.cache[i + (-IntegerCache.low)]; 这是什么?一探究竟:

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

  原来是做了缓存,到在 Java 5 中,Integer.valueOf()方法基于减少创建对象次数和节省内存的考虑,缓存了[-128,127]之间的数字,这种 Integer 缓存策略仅在自动装箱的时候有用,使用构造器创建的 Integer 对象不能被缓存。

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

Integer a = 10; //this is autoboxing
Integer b = Integer.valueOf(10); //under the hood

  java内部为了节省内存,IntegerCache类中有一个数组缓存了值从-128到127的Integer对象。当我们调用Integer.valueOf(int i){这一步自动装箱就会用到}的时候,如果i的值时结余-128到127之间的,会直接从这个缓存中返回一个对象,否则就new一个新的Integer对象。
即:当我们定义两个Integer的范围在【-128—+127】之间,并且值相同的时候,用==比较值为true;

       当大于127或者小于-128的时候即使两个数值相同,也会new一个integer,那么比较的是两个对象,用==比较的时候返回false

其他缓存的对象

这种缓存行为不仅适用于Integer对象。我们针对所有整数类型的类都有类似的缓存机制。

有 ByteCache 用于缓存 Byte 对象

有 ShortCache 用于缓存 Short 对象

有 LongCache 用于缓存 Long 对象

有 CharacterCache 用于缓存 Character 对象

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

 

posted @ 2020-01-27 20:10  字节悦动  阅读(280)  评论(0)    收藏  举报