涨点知识:Java基本数据类型的包装类Integer的缓存了解吧?

涨点知识:Java基本数据类型的包装类Integer的缓存了解吧?

一、Java中对象的比较

我们都知道,Java的对象名其实是一个引用,指向堆中的某个位置,如果两个对象指向同一个位置,那么用==号比较两个对象,得到的结果就是true。而如果两个对象指向内存中不同位置,那么用==号比较的话,会得到false,这个时候要去重写对象的equals方法来进行比较。

二、Integer中的==比较

涨点知识:Java基本数据类型的包装类Integer的缓存了解吧?

如上图所示,写了一段代码,来比较a和b,c和d。大家猜一下答案应该是什么呢?

涨点知识:Java基本数据类型的包装类Integer的缓存了解吧?

是不是很奇怪?

通过上述代码,我们可以得出,a和b其实指向的是同一个对象,而c和d则指向的是不同的对象

让我们去看看这个类的字节码。在IDEA左侧导航栏中单击这个类:

涨点知识:Java基本数据类型的包装类Integer的缓存了解吧?

然后点击view,找到show bytecode,可以查看字节码:

涨点知识:Java基本数据类型的包装类Integer的缓存了解吧?

看不懂没关系,我们注意到,当执行Integer a = 100,这条语句的时候,调用的是Integer.valueOf方法。那么我们去追踪一下这个方法。

按住ctrl(mac上是command),左键单击Integer,即可进入Integer类。

涨点知识:Java基本数据类型的包装类Integer的缓存了解吧?

我们搜索一下这个类的valueOf方法,代码如下:

可以看到,当输入处于IntegerCache.low 和 IntegerCache.high之间的时候,返回的是IntegerCache中的cache数组的值。而大于那个范围,才是另外去new一个Integer。

让我们继续追踪,什么是IntegerCache?

它是Integer中的一个静态内部类,里边有一个Integer数组,用来存储-128到127的值。

涨点知识:Java基本数据类型的包装类Integer的缓存了解吧?

所以答案解开了,因为a和b都是指向IntegerCache中的值为100的那个Integer对象,所以进行==比较的结果返回true。而c和d大于127,所以每次都会重新new一个Integer对象,所以c和d指向的不是内存中的同一个地方,因此==比较的时候会返回false。

三、为什么引入IntegerCache

IntegerCache是JDK1.5中被引入的,因为这些小数字在生活中被频繁使用,如果每次使用都去重新new的话,会带来性能开销。在第一次使用Integer的时候,IntegerCache中的cache数组就被初始化好。每次用等号给Integer赋值的时候,都会检查是否在-128和127之间。

注意:只有用=给Integer赋值,才会自动装箱,隐式去调用valueOf。如果直接new的话,IntegerCache并不起作用:

涨点知识:Java基本数据类型的包装类Integer的缓存了解吧?

上边的代码输出为false。

四、其他包装类

Byte,Short,Long,Character都有类似于Integer的缓存,其中除了Character是0~127之外,其他的都是-128~127。大家感兴趣的可以去看看源码。另外Integer的Cache范围可以通过JVM启动参数来设置,而其他的不行。

涨点知识:Java基本数据类型的包装类Integer的缓存了解吧?


一般来说,如果没有什么特别用途,这类问题,可能永远都不会关注,但有面试官喜欢问,以检验你的基本功咋样。所以,就多积累吧,涨点见识也不错嘛~


看完了,记得关注、分享、点个赞啥的^_^


分享到:


相關文章: