关于IntegerCache的探讨

在importNew上看到了这么一个问题,这次给各位看官分享下。
问题描述如下:

@Test
public void test(){
Integer s1=100,s2=100;
Integer c1=1000,c2=1000;
System.out.println(s1==s2);//true
System.out.println(c1==c2);//false
}

各位看官可能都知道,Integer为int的封装类型,在使用==比较时,会进行地址比较,那么为何100的时候相等而1000的时候又不相等呢?

首先我们来看看一个小问题,知道答案的看官请保持沉默,让不知道的看官思考下:
对于Integer s1=100;的赋值过程是怎么样的?是调用了构造函数还是怎么样的?
[b]loading.........[/b]
下面揭晓答案,这位看官说的很对,是调用了Integer里面的一个方法[b]valueOf[/b],为了证明这一点,我们使用javap -c Test来看看class文件

[img]http://dl2.iteye.com/upload/attachment/0121/4896/89d785b4-e757-3ccd-b2a2-98bc917c9cf7.png[/img]

可以看出确实是调用了valueOf方法来完成赋值,接着我们来看看Integer中valueOf的源码


public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
//在[-128,127]这个值域的数据,采用缓存
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}


再看看Integer的源码。

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) {
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);
}
high = h;

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

通过以上源码我们发现,Integer里面包含了一个内部类IntegerCache ,可想而知,其主要功能就是用于缓存值域为[-128,127],当然上限是可以设置的,由于这个区域的数字为常用的数字,故而做此处理来提高效率,节约内存。所以在[-128,127]这个区域里面的数字,数字相同的均指向同一个引用,而在此之外的数字则不会被缓存,从而引用不同,故而得到上述的结果。
接下来,咱们趁热打铁实践下,看看这一段代码,看官们也可以自己试试看。

@Test
public void test(){
Class cache=Integer.class.getDeclaredClasses()[0];
Field myCache=cache.getDeclaredField("cache");
myCache.setAccessible(true);
Integer[]newCache=(Integer[])myCache.get(cache);
newCache[132]=newCache[133];
int a=2;
int b=a+a;
System.out.printf("%d + %d = %d", a, a, b);
}

此处我们运用反射来改变cache数组中的值,由源码分析可以得到下图:

[img]http://dl2.iteye.com/upload/attachment/0121/4882/e2d62887-cc4d-3b1d-b17a-a338c7582589.png[/img]

这个故事告诉我们要多多看源码,好了,撸代码去了,就酱 :arrow:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值