0%

Java Integer缓存

Integer的缓存机制是怎么回事?

学会看字节码就知道自动装箱拆箱实际调用的是什么。

Intellij idea里通过View - Show Bytecode

以Integer为例

Integer a = 3;

字节码指令为

1
2
3
ICONST_3
INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
ASTORE 3

看到调用的是Integer.valueOf()方法

Integer.valueOf()内部会用到IntegerCache,默认-128到127的Integer对象都会被缓存,通过valueOf()返回这个范围内的Integer对象都是同一个

两个值相等的Integer对象,==比较,是否相等?

要看Integer对象是如何从创建出来的。

如果Integer是new出来的,==比较对象的内存地址,肯定不相等。

如果Integer是通过Integer.valueOf()创建出来的,如果值是[-128,127]之间的数,会用缓存的Integer对象,即是同一个Integer对象。

其中自动装修也会调用Integer.valueOf()方法生成Integer对象,触发自动装箱的代码如 Integer a = 3。

其他基本类型的包装类是否跟Integer一样都有Cache?

Java的基本类型有八种:

  1. 字符类型:char
  2. 布尔类型:boolean
  3. 数值类型:
    1. 整数类型:byte、short、int、long
    2. 浮点数类型:float、double

整数类型Byte、Short、Integer、Long都有Cache机制,缓存的数值范围都是[-128,127]。

字符类型Character有Cache机制,缓存范围[0,127]的ASCII字符。

布尔类型Boolean有Cache机制,定了两个TRUE和FALSE的常量,通过Boolean.valueOf(boolean b)返回的都是这两个常量的其中之一。

浮点数类型没有Cache机制,valueOf方法都是直接new一个Float或Double对象;某个范围内整数数值是有限个的,所以缓存有意义,命中率也高,而浮点数某个范围内的数值个数是无穷多个,即使做缓存,缓存命中率低,没有起到缓存的作用,反而占用了存储空间,故而浮点数不需要缓存。