Integer中的IntegerCache内部类

面试题

碰到一个面试题。对于这个面试题,大部分人的回答,要不全是false,要不全是true,但事后运行下,结果却是true false, 为什么会出现不一致的现象?

public class Test03
{
    public static void main(String[] args) throws Exception {
        Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;
        // 对于引用类型的变量之间的比较是引用,而非变量的值
        System.out.println(f1 == f2);
        System.out.println(f3 == f4);
    }
}

原理解析

首先,需要了解 java 中的自动装箱、拆箱机制。拿上面的赋值语句Integer f1 = 100来举例,当100这个int值赋给Integer这个对象时,就会出现装箱现象,也就是把基本类型包装成引用类型,系统为我们执行了:Integer i = Integer.valueOf(100); 查阅下Integer源码,就会发现如果在某个范围内,会直接从这个IntegerCache中获取。那我们再来看下这个IntegerCache源码,原来IntegerCache是Integer的内部类,同时也发现,就是Integer内部实现了一个缓存机制。缓存的范围为-128 到 127(这个值可以进行设置),当被赋的值在这个范围内的时候,就直接从缓存池中取。
现在回到面试题中,f1 和 f2 被赋的值均为100,在这个范围内,所以这两个变量其实引用的是同一个值。与此同时,使用引用类型的变量使用== 进行比较时,其实比较的两个对象的引用,故而f1 == f2 结果为 true。而 f3 和 f4 被赋的值超出了范围,需要new 一个 Integer对象出来,引用肯定是不同的,所以结果为false。

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

    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中其他缓存的对象

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值