Integer的缓存机制是怎么回事?
学会看字节码就知道自动装箱拆箱实际调用的是什么。
Intellij idea里通过View - Show Bytecode
以Integer为例
Integer a = 3;
字节码指令为
1 | ICONST_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的基本类型有八种:
- 字符类型:char
- 布尔类型:boolean
- 数值类型:
- 整数类型:byte、short、int、long
- 浮点数类型: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对象;某个范围内整数数值是有限个的,所以缓存有意义,命中率也高,而浮点数某个范围内的数值个数是无穷多个,即使做缓存,缓存命中率低,没有起到缓存的作用,反而占用了存储空间,故而浮点数不需要缓存。