【Java】Integer的缓存机制

InterviewCoder

# Integer 的缓存机制

# 文章目录

# 一 现象

在引入 Integer 的缓存机制前,可以先判断一下以下几种情况

1
2
3
4
5
6
7
8
9
10
11
12
   # 一:自动装箱
Integer s1 = 2;
Integer s2 = 2;
System.out.println(s1 == s2);
# 答案为true

# 二:
Integer s1 = new Integer(2);
Integer s2 = new Integer(2);
System.out.println(s1 == s2);
# 答案为false

情况二很好理解,虽然传值相同,但是 Integer 是包装类,不同对象的引用地址是不一样的,而 “==” 比的是引用地址,那为什么情况一中会得到结果 true
这里就不得不提到 Integer 的缓存机制了

# 二 Integer 的缓存机制

# 2.1 自动装箱等效于 valueOf

1
2
3
4
#以上代码的情况一的自动装箱等效于Integer中的ValueOf()方法,如下:
Integer s1 = Integer.valueOf(2);
Integer s2 = Integer.valueOf(2);
System.out.println(s1 == s2);

# 2.2 valueOf

以下是 valueOf () 方法的具体实现

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

可以看见,其实现方式和 IntegerCache 有关

# 2.3 IntegerCache

IntegerCache 是 Interger 的一个静态内部类,实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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;
}

可以看到,默认情况下,该静态内部类会直接缓存 - 127 到 128 的 Integer 对象,因此,在 valueOf () 方法中,如果值在 - 127-128 之间,都会直接返回缓存中的该对象而不会重新生成对象,引用地址当然相同了。
而且 java5 引入时,该范围还是固定的,而在 java6 之后,Integer 的缓存中还可以通过 Integer.IntegerCache.high 来设置最大值。由于这个缓存机制,程序中第一次使用 Integer 的时候还需要一定的时间家长该缓存类

# 三 为什么要有缓存机制

# 3.1 原因

因为我们常见的基本数据类型中,使用包装类包装数值时会创建大量对象,如果没有缓存的话,会有大量的包装类被创建,占用内存,降低效率。选择最常用的数值范围设置缓存机制,就可以优化这一现象

# 3.2 其他包装对象的缓存

既然缓存机制的原因我们知道了,那除了 Integer 之外,其他包装类有这种缓存机制吗?肯定是有的

  • ByteCache:缓存 Byte 对象
  • ShortChche:缓存 Short 对象
  • LongChche:缓存 Long 对象
  • CharacterChche:缓存 Character 对象
    Byte,Short,Long 的缓存范围都是 - 128-127,Character 的缓存范围是 0-127,除了 Integer,其他的缓存范围都是固定的

# 关于我

Brath 是一个热爱技术的 Java 程序猿,公众号「InterviewCoder」定期分享有趣有料的精品原创文章!

InterviewCoder

非常感谢各位人才能看到这里,原创不易,文章如果有帮助可以关注、点赞、分享或评论,这都是对我的莫大支持!

评论