IntegerCache

目录

 

起因

探究

总结

扩展


起因

在阅读《阿里巴巴开发手册》时发现了一句话:

【强制】 所有整型包装类对象之间值的比较, 全部使用equals方法比较。

说明:对于Integer var = ?在-128至127之间的赋值,Integer对象是在IntegerCache.cache产生,会复用已有对象,这个区间内的Integer值可以直接使用==进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,这是一个大坑,推荐使用equals方法进行判断。

探究

public static Integer valueOf(String s) throws NumberFormatException {
    return Integer.valueOf(parseInt(s, 10));
}

public static Integer valueOf(int i) {

        if (i >= IntegerCache.low && i <= IntegerCache.high)

            return IntegerCache.cache[i + (-IntegerCache.low)];

        return new Integer(i);

}

通过代码我们可以看到valueOf(String)最终调用的是valueOf(int)方法;

在valueOf(int)方法中则是调用IntegerCache.cache[],而这个[]则是数组的标志,难道是从数组里获取数据吗?

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

}

就是当JVM属性java.lang.Integer.IntegerCache.high为空的时候,则定义2个极限值:最小值-128,最大值127;

然后定义一个Integer[]数组,数组长度为128 + 127 +1=256,然后通过一个for循环,从数组下标0开始,从-128依次递增,即

Integer[0]=-128

Integer[1]=-127

Integer[2]=-126

...............

Integer[255]=127

总结

如果Integer的数值是在-128 ~ 127这个区间,那么有很大可可能性是复用Integer[]里的内容,因此,建议使用equels来判断,而不是用==来判断;

扩展

对于Long类、Short类,JDK同样做了缓存操作,区别在于他们不能调整high值,后续再遇到包装类的时候,要注意下,最好看一下源码;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值