【Java】关于Integer包装类的一个坑

这也算是一道面试题,很多初学者在看到以下代码的时候第一反应就是输出两个true,其实不然。

public class IntegerTest {
	public static void main(String[] args) {
		Integer a = 100;
		Integer b = 100;
		
		Integer c = 1000;
		Integer d = 1000;
		
		System.out.println(a == b);
		System.out.println(c == d);
	}
}

博主当初的反应也是一样,认为两个结果都为true,但实际的运行结果如下:

true
false

源码分析

很多没看过源码的小伙伴会和博主一样一头雾水(跟想象的完全不一样嘛)。
其实不用怀疑人生,我们看下Integer的源码就知道为什么会出现上述结果(我这里是jdk1.8的源码),这里仅摘取关键部分源码。

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

从这段代码中我们可以看到,Integer对象在其内部是有缓存机制的,它缓存区间的值在-128~127之间,存放在自定义的cache数组当中。
而对于我们的Integer a = 100来说,它实际在内部做了Integer a = Integer.valueOf(100)类似的操作,所以我们再来看下valueOf这个方法的具体操作,代码如下:

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

IntegerCache静态内部类中,我们发现IntegerCache.low的值为-128IntegerCache.high的值为127
valueOf(int i)这个方法很明显的意思就是说:

  • 如果传入的值在区间-128~127之间,则从Integer包装类的静态内部类IntegerCache中的cache数组中取出对应的缓存对象。
  • 如果传入的值不在区间-128~127之间,那么新建一个Integer包装对象。

换句话说,对于Integer var = ?这种在-128~127区间的赋值,Integer对象是在Integer.IntegerCache.cache中产生,所以可以复用已经存在的对象,也就是说在这个区间内的Integer值可以直接使用==来进行判断。而在这个区间之外的数该如何判断?在这个区间之外的数都会在堆上产生一个新的对象,从而不会复用已经存在的对象,所以这个时候==就不能够对其进行判断,而应该使用equals方法来判断。
因此,上面题目中的c == d结果为什么是false也就说得通了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值