一.缓存池的存在
1.创建Integer对象
在Java中,Integer是一个包装类,用于将基本数据类型int包装成一个对象。下面就是一个简单的示例,通过这个示例,我们可以得到, n1和n2通过"=="和"equals()"比较结果都为true,说明二者的内存地址和值是都是相同的;而n3和n4通过"=="和"equals()"比较结果一个为false,一个为true,由此可说明,两者的内存地址不同,但值相同。
2.缓存池的存在
由此我们可以知道,Ineger内部存在缓存池,也称为IntegerCache,是Integer类的一个静态内部类,用于缓存特定范围内的Integer对象,即-128到127之间的整数对象,当超过这个范围时,会创建一个新的内存空间,所以当二者通过"=="相比时返回值为false,即内存地址不相同。
二.阅读源代码
1.类的定义
- 定义了一个内部类IntegerCache
- 通过final关键字定义了缓存池的最小值low为-128
- 通过final关键字定义了缓存池的最大值,未设置初始值
- 通过final关键字定义了一个Integer类型的数组,用来存储缓存的Integer对象
2. 静态代码块的创建
- 定义了一个静态代码块,当类加载时就会执行一次
- 设置h初始值为127
- 定义字符串integerCacheHighPropValue用来存储java.lang.Integer.IntegerCache.high 的值
- 通过if语句判断integerCacheHighPropValue不为空时,则更新h的值
- 将字符串integerCacheHighPropValue转为整数i
- 定义i的值不能小于127
- 计算h的值,避免出现溢出,确保在一个安全的范围内
- 利用try{}catch{}语句捕获NumberFormatException数字格式化异常,并忽略它
- 将h的值赋给high
3.初始化数组
- 创建一个Integer类型的数组cache,长度由缓存池范围的high和low决定
- 定义一个j,将low值赋给它
- 通过for循环,给数组cache的low到high区间内的每一个元素分配了一个Integer对象
- 保证high值不能小于127
三.Integer.valueOf()方法
1.自动装箱和拆箱
自动装箱是将基本类型转换为引用类型,自动拆箱是将引用类型转换为基本类型。当将一个int类型的值转换为Integer时,调用了valueOf()方法完成装箱过程,当将一个Integer类型转换为int类型时,会调用intValue()方法完成拆箱过程。
2.valueOf()方法对于缓存池的意义
Integer内部存在缓存池IntegerCache,用于存储Integer的缓存对象,通过调用valueOf()方法可以直接从缓存池中返回该值的Integer对象,前提是数值必须在缓存池范围之内。以下是一个简单的举例,将n1的值赋给n2是装箱的过程,通过valueOf()方法创建n3,此方法创建的值不会产生新的存储空间,这样可以避免频繁创建新的内存,减少内存占用空间。所以,valueOf()方法通过利用缓存池机制,实现了性能优化和内存管理的双重效益。它减少了相同值Integer对象的创建和销毁次数,提高了比较操作的效率,并减少了内存占用和垃圾回收的开销。