包装类型中的缓存池
基本类型 vs 包装类型
缓存池
缓存池也叫常量池。它是事先存储一些常量数据用以提高性能节省空间的一种技术,大部分的包装类型都实现了缓存池。
当我们在自动装箱时,如果基本类型的值处在缓存的范围内,则不会重新创建对象,而是复用缓存池中已事先创建好的对象。
比如我们将数值8装箱为两个Integer对象,然后一比较就会发现这两个Integer是同一个对象,即比较结果为true。
而当我们将数值128装箱为两个Integer对象,经过比较便会发现,这两个Integer不是同一个对象,即比较结果为false。
这是因为Integer类型默认缓存了[-128, 127]范围的值。只要是这个范围的值自动装箱,便会返回相同的对象,所以如果是包装类型,互相比较的话,不要用==判断,而要用equals()方法判断。
不同的包装类缓存的范围不同,参考这个表格即可。
自动装箱和拆箱背后的原理
当我们查看自动装箱/拆箱的字节码时便会发现,自动装箱实际上是调用了包装类型的valueOf()方法,拆箱实际上是调用了xxxValue()方法。
我们点进valueOf()方法,就可以看到缓存池的代码了,缓存的范围、缓存的位置以及缓存返回的方式都这里被解释了。
在创建包装类对象时,要么使用自动装箱,要么使用valueOf()方法,而不要直接new。因为valueOf()方法利用了缓存,而直接new时直接创建对象没有利用缓存。