作者| 慕课网精英讲师明明如月
本文首发自「慕课网」,想了解更多IT干货内容,程序员圈内热闻,欢迎关注!
我们先看下面的示例代码,并思考该段代码的输出结果:
- public class IntTest {
- public static void main(String[] args) {
- Integer a = 100, b = 100, c = 150, d = 150;
- System.out.println(a == b);
- System.out.println(c == d);
- }
- }
通过运行代码可以得到答案,程序输出的结果分别为: true , false。
那么为什么答案是这样?
很多人可能会颇有自信地回答:因为缓存了 -128 到 127 之间的数值,就没有然后了。
那么为什么会缓存这一段区间的数值?缓存的区间可以修改吗?其它的包装类型有没有类似缓存?
what? 咋还有这么多问题?这谁知道啊!
莫急,且看下面的分析。
首先我们可以通过源码对该问题进行分析。
我们知道,Integer var = ? 形式声明变量,会通过 java.lang.Integer#valueOf(int) 来构造 Integer 对象。
很多人可能会说:“你咋能知道这个呢”?
如果不信大家可以打断点,运行程序后会调到这里,总该信了吧?(后面还会再作解释)。
我们先看该函数源码:
- /**
- * Returns an {@code Integer} instance representing the specified
- * {@code int} value. If a new {@code Integer} instance is not
- * required, this method should generally be used in preference to
- * the constructor {@link #Integer(int)}, as this method is likely
- * to yield significantly better space and time performance by
- * caching frequently requested values.
- *
- * This method will always cache values in the range -128 to 127,
- * inclusive, and may cache other values outside of this range.
- *
- * @param i an {@code int} value.
- * @return an {@code Integer} instance representing {@code i}.
- * @since 1.5
- */
- public static Integer valueOf(int i) {
- if (i >= IntegerCache.low && i <= IntegerCache.high)
- return IntegerCache.cache[i + (-IntegerCache.low)];
- return new Integer(i);
- }
通过源码可以看出,如果用 Ineger.valueOf(int) 来创建整数对象,参数大于等于整数缓存的最小值( IntegerCache.low )并小于等于整数缓存的最大值( IntegerCache.high), 会直接从缓存数组 (
java.lang.Integer.IntegerCache#cache) 中提取整数对象;否则会 new 一个整数对象。
那么这里的缓存最大和最小值分别是多少呢?
从上述注释中我们可以看出,最小值是 -128, 最大值是 127。
那么为什么会缓存这一段区间的整数对象呢?
通过注释我们可以得知:如果不要求必须新建一个整型对象,缓存最常用的值(提前构造缓存范围内的整型对象),会更省空间,速度也更快。
这给我们一个非常重要的启发:
如果想减少内存占用,提高程序运行的效率,可以将常用的对象提前缓存起来,需要时直接从缓存中提取。
那么我们再思考下一个问题: Integer 缓存的区间可以修改吗?
通过上述源码和注释我们还无法回答这个问题,接下来,我们继续看
java.lang.Integer.IntegerCache 的源码: