Integer 的缓存机制

在了解 Integer 的缓存机制之前,先了解一下装箱和拆箱。
Integer --> int 拆箱 intValue();
int --> Integer 装箱 valueOf();

一、什么时候触发装箱、拆箱?

1.1 装箱

将一个 int 的数值,赋值给一个 Integer 引用会触发装箱过程。如:

Integer a = 10;		//等价于	Integer a = Integer.valueOf(10);

由于10为 int 类型,在赋值给 a 时,会先调用 valueOf() 方法从缓存中取出一个 Integer 对象或者创建一个值为 10 的 Integer 对象(valueOf() 方法后面具体再详述)。

1.2 拆箱

① 将一个 Integer 的包装类型对象赋值给 int 类型的变量,如:

Integer a = 10;			//上面说到,该语句会触发装箱过程,返回一个 Integer 对象
int b = a;				//将 Integer 类型变量赋值给 int 类型变量,会触发拆箱过程
						//等价于 int b = a.intValue();	直接返回一个 int 的值

② 进行运算符运算时

Integer a = 10;
Integer b = 20;
System.out.println(a * b);//触发拆箱过程,等价于	a.intValue() * b.intValue()

注意:当进行 == 运算时,若两个数据类型都为 Integer 时,它们将直接比较这两个 Integer 对象是否一样;若有一个数据类型为 int ,另外一个数据类型为 Integer 时,Integer 的数据将进行拆箱转换为 int,然后再进行比较值是否相等。如:

Integer a = 10;
Integer b = 10;
int c = 10;

System.out.println(a == b);	//等价于 Integer.valueOf(10) == Integer.valueOf(10) ;	true
System.out.println(a == c);	//等价于 a.intValue() == c		true

二、Integer 缓存机制

当在进行装箱操作时,需要装箱的值的大小处于 -128 到 127 时,调用 Integer.valueOf() 方法将会从缓存中直接取出已经预先创建好的 Integer 对象;当数值不处于 【-128,127】区间时,将会直接 new Integer();进行新创建一个对象。

查看 Integer 的 valueOf() 方法的源码:

    public static Integer valueOf(int i) {
    	// IntegerCache.low = -128, IntegerCache.high = 127
        if (i >= IntegerCache.low && i <= IntegerCache.high)
        	// cache 是一个存放着值为 -128 到 127 的 Integer 数组
        	//从缓存数组直接取对应的 Integer 对象
            return IntegerCache.cache[i + (-IntegerCache.low)];
        
        //数值不在 [-128, 127] 区间,直接 new 一个 Integer 对象
        return new Integer(i);
    }

查看 IntegerCache 类源码(Integer 的缓存类):

    private static class IntegerCache {
        static final int low = -128;
        static final int high;
        //缓存数组,用来存放 -128 到 127 的 Integer 对象
        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 = 127
            high = h;

			// 创建一个大小为 256 的 Integer 对象数组
            cache = new Integer[(high - low) + 1];
            // low = -128
            int j = low;
            // 从 -128 开始到 127 结束,每个数值创建一个 Integer 对象,并把该对象放置到 cache 数组中
            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() {}
    }

IntegerCache 类是 Integer 的一个内部类,该类的主要功能是存储 [-128, 127] 范围的 Integer 对象。

验证:

Integer a = 10;
Integer b = 10;
Integer c = 128;
Integer d = 128;

System.out.println(a == b);		//true
System.out.println(c == d)		//false

a == b 的结果为 true 是因为它们都会进行装箱,调用 valueOf() 方法,且大小在 [-128, 127],直接从缓存数组中直接取出,取出的 Integer 对象是同一个对象,所以 a == b 为 true
c == d 的结果为 false,是因为其值不在 [-128, 127] 范围内,会直接 new 一个 Integer 对象(每new 一个对象,它们就会内存的不同位置创建对象)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值