Integer.IntegerCache 缓存问题总结

抛出问题,先上代码:
image.png

执行结果:
image.png


为何一个是 true,一个是 false,不是完全一样?

根据Java编译机制, .java文件在编译以后会生成.class文件供JVM加载执行,那么我们先到.class文件中看看是否能解释以上原因。

如何找到对应的.class文件?我的项目是maven项目,故编译后可以到项目根目录的 target 目录下找到对应 .class文件。
image.png

打开文件(idea自带的反编译工具):
image.png

有几处不同:

  • 首先编译器为我们的类自动添加了一个 无参构造函数
  • 其次 main 入口处也有两处不同,一个是 格式化代码,另一个是 Integer类型的 引用指向 被Integer.valueOf()改变。


查看valueOf源码:

image.png

我们发现,Integer 类的作者在编写该类时,为避免重复创建对象,对 Integer 部分值的实例做了缓存,如果创建的值在 low 和 high 范围内,直接从 IntegerCache中取出缓存好的对象,否则 new 一个新的 Integer对象返回。下面看一下IntegerCache这个类,该类是 Integer 类的私有静态内部类

image.png

该类位于 Integer.java 内部,该类会在 static 代码块初始化时加载JVM的配置,如果能够加载到对应的值就使用配置值,否则用默认的 -128到 127的范围初始化缓存数组。

现在回过头来看一开始的代码:
image.png
结论:
  • (来自方法注释) This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.
  • (来自方法注释) If a new Integer instance is not required, this method should generally be used in preference to the constructor, as this method is likely to yield significantly better space and time performance by caching frequently requested values.
  • 在比较Integer对象的值时,不要使用“==”,一定要使用 equals()。


原文作者:清浅池塘
原文链接:https://zhuanlan.zhihu.com/p/27562748

推荐阅读更多精彩内容