杂谈——Integer的缓存机制

这个问题很多人其实都知道——如果值在-128到127之间,Integer对象的引用地址是相等的。身边很多朋友都说是字面量在常量池中缓存的原因。

其实并不是的,这是Integer的缓存机制

在Integer类中,定义了一个私有的静态类IntegerCache,这个类是用来支持Integer缓存的,它的作用是把一部分Integer类型的对象在Integer类加载的时候一起创建出来并放在一个cache数组中,以便以后循环使用。

Integer缓存是有范围的,通常这个范围是-128~127即256个数。

不过,这个范围的最大值是可变的,可以通过-XX:AutoBoxCacheMax=<size>参数去修改这个值,在JVM初始化的时候,这个值被写入sun.misc.VM class系统私有配置文件中,并加载。(不过因为要缓存的这些数会一次性全部创建出来,所以这个数值太大的话会影响到启动性能)

注:除了 Integer 可以通过参数改变范围外,其它的都不行。Byte,Short,Long 有固定范围: -128 到 127。对于 Character来说, 范围是 0 到 127。

创建cache数组的相关源码如下: 

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

我们在调用valueOf(int i)方法的时候(自动封装就是调用这个方法),就会判断 i 是否在这个范围之内,是的话就会返回这个静态类维护的cache数组里对应的对象。所以说在这个范围内值相同的对象的引用是相同的。

valueOf(int i)的源码如下:

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

示例:

Integer integer1 = new Integer(121);
Integer integer2 = 121; // 编译器编译成调用valueOf(int i)
Integer integer3 = Integer.valueOf(121);

System.out.println(integer1 == integer2);  // false
System.out.println(integer2 == integer3);  // true

从上面这个例子我们可以发现,integer2和integer3都会从缓存中取,而 new出来的对象并不会从Integer缓存中去取。

好啦,以上就是关于Integer缓存机制的相关知识总结,如果大家有什么不明白的地方或者发现文中有描述不好的地方,欢迎大家留言评论,我们一起学习呀。

Biu~~~~~~~~~~~~~~~~~~~~宫å´éªé¾ç«è¡¨æå|é¾ç«gifå¾è¡¨æåä¸è½½å¾ç~~~~~~~~~~~~~~~~~~~~~~pia!

猜你喜欢

转载自blog.csdn.net/Searchin_R/article/details/85289691