你真的懂Integer的缓存机制吗?

Integer的缓存机制

介绍
Integer首次使用时会初始化缓存,默认情况下,缓存[low, high]范围内的数,low = -128(无法修改),high = 127(默认),可以通过-XX:AutoBoxCacheMax=[size]来指定大小(注意: size一定要大于127,否则high = 127,但是不能大于Integer.MAX_VALUE,否则会报错),max(high) = Integer.MAX_VALUE - (-low) -1。
源码

private static class IntegerCache {
	// 缓存最低为-128,不可以修改
	static final int low = -128;
	static final int high;
	static final Integer cache[];

	static {
		// 默认缓存为127
		int h = 127;
		// 读取-XX:AutoBoxCacheMax的值
		String integerCacheHighPropValue =
			sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
		// 判断有没有使用-XX:AutoBoxCacheMax修改high的值
		if (integerCacheHighPropValue != null) {
			try {
				// size不能大于Integer.MAX_VALUE,否则会报错
				int i = parseInt(integerCacheHighPropValue);
				// size一定要大于127,否则白配置
				i = Math.max(i, 127);
				// max(cache.length) = Integer.MAX_VALUE
				h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
			} catch( NumberFormatException nfe) {
				
			}
		}
		high = h;

		cache = new Integer[(high - low) + 1];
		int j = low;
		for(int k = 0; k < cache.length; k++)
			cache[k] = new Integer(j++);

		
		assert IntegerCache.high >= 127;
	}

	private IntegerCache() {}
}

情况一
new一个Integer对象,直接在堆中创建对象,不使用缓存。
情况二
Integer integer = [value]; //value 为int型
自动装箱操作,若value在[low, high]范围内,则使用缓存,否则相当于情况一
情况三
调用valueOf方法,底层最终会进行与情况二一样的判断。valueOf(String s)会调用valueOf(int i)。
valueOf(int i)源码

public static Integer valueOf(int i) {
	// 判断i是否在缓存范围内,若在返回缓存中的Integer对象,否则返回新创建的Integer对象
	if (i >= IntegerCache.low && i <= IntegerCache.high)
		return IntegerCache.cache[i + (-IntegerCache.low)];
	return new Integer(i);
}

看了上面的介绍之后,下面的题目应该没有什么问题。
使用默认的缓存范围[-128, 127],请给出以下代码的输出结果。

public class IntegerTest {
    public static void main(String[] args) {
        // 使用默认的缓存范围[-128, 127]
        // 举几个在这个范围内的例子
        Integer i1 = new Integer(100);
        Integer i2 = 100;
        System.out.println("i1 == i2的结果为:" + (i1 == i2));
        Integer i3 = new Integer("100");
        System.out.println("i2 == i3的结果为:" + (i2 == i3));
        Integer i4 = Integer.valueOf(100);
        System.out.println("i2 == i4的结果为:" + (i2 == i4));
        Integer i5 = Integer.valueOf("100");
        System.out.println("i2 == i5的结果为:" + (i2 == i5));
        System.out.println("-----------------------");
        // 举几个不在这个范围内的例子
        Integer i6 = 160;
        Integer i7 = Integer.valueOf(160);
        System.out.println("i6 == i7的结果为:" + (i6 == i7));
        // parseInt方法返回int型,会进行自动装箱,与文中提到的情况二一样
        Integer i8 = Integer.parseInt("160");
        System.out.println("i6 == i8的结果为:" + (i6 == i8));
    }
}

结果如下

i1 == i2的结果为:false
i2 == i3的结果为:false
i2 == i4的结果为:true
i2 == i5的结果为:true
-----------------------
i6 == i7的结果为:false
i6 == i8的结果为:false

使用-XX:AutoBoxCacheMax=[size]来修改缓存范围。
设置size为500。此时范围为[-128, 500] 下面讲一下如何设置,我使用的是IDEA。首先打开Run/Debug Configurations界面(点击Run上的Edit Configurations… 即可。还有其他方法,请自行发现。),然后找到你要修改的类(文中为IntegerTest)。
在这里插入图片描述
使用已修改的缓存范围[-128, 500],请给出以下代码的输出结果。

public class IntegerTest {
    public static void main(String[] args) {
        // -XX:AutoBoxCacheMax=500,即缓存范围为[-128, 500]
        // 举几个在这个范围内的例子
        Integer i9 = new Integer(200);
        Integer i10 = 200;
        System.out.println("i9 == i10的结果为:" + (i9 == i10));
        Integer i11 = new Integer("200");
        System.out.println("i10 == i11的结果为:" + (i10 == i11));
        Integer i12 = Integer.valueOf(200);
        System.out.println("i10 == i12的结果为:" + (i10 == i12));
        Integer i13 = Integer.valueOf("200");
        System.out.println("i10 == i13的结果为:" + (i10 == i13));
        Integer i14 = 500;
        Integer i15 = Integer.valueOf(500);
        System.out.println("i14 == i15的结果为:" + (i14 == i15));
        System.out.println("-----------------------");

        // 举几个不再这个范围内的例子
        Integer i16 = -200;
        Integer i17 = Integer.valueOf(-200);
        System.out.println("i16 == i17的结果为:" + (i16 == i17));
        Integer i18 = 501;
        Integer i19 = Integer.valueOf(501);
        System.out.println("i18 == i19的结果为:" + (i18 == i19));

    }
}

结果如下

i9 == i10的结果为:false
i10 == i11的结果为:false
i10 == i12的结果为:true
i10 == i13的结果为:true
i14 == i15的结果为:true
-----------------------
i16 == i17的结果为:false
i18 == i19的结果为:false

嘻嘻,不知道你都答对了吗?如果都答对了,那恭喜你了。如果没有全答对,在思考一下我上面讲的缓存机制。如果你感觉代码中写的例子没有覆盖全部的情况,请自行操作。整篇文章如果有不对的地方,请在评论区留言哦,我会定期查看。希望对你有用。。。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值