面试题分享——深入剖析Integer缓存机制
一. 问题展现
我们在面试的时候,面试官往往会给面试者洒出一些迷雾,用来迷惑面试者,这时往往就需要面试者掌握底层源码,才能对问题进行较好的回答。接下来就以Integer的缓存数组为例,通过分析其源码来教会大家该如何应对带有迷惑性的面试。
为了讲解清楚,给大家设计了一段代码如下,我们可以运行下面这段代码:
上面这段代码中,其实就涉及到了关于Integer缓存机制相关的一些面试题,比如面试官会问我们,”你知道Integer的缓存机制吗“,”Integer.valueOf()方法的源码你熟悉吗?“,”int和Integer的区别有哪些“......
二. 结果分析
上面代码输出的结果应该是:
true
false
上面代码中有两个不一样的输出结果,本来明明以为是一样的结果,其实却不然!为什么这两个输出的结果一个是true,另一个却是false呢?
其实这里,num1和num2是在Integer的缓存数组中直接获取的整型缓存对象!而num3和num4却都是在直接new出来的Integer对象。至于为什么会这样,结合Integer的源码对这个问题进行详细说明。
三. 源码解析
反编译结果
表面上看,上面的代码中都是把int类型的数值赋给了一个Integer引用类型。但是我们知道,一个基本的数据类型赋值给引用类型会进行装箱操作。那么Integer类又是如何将一个基本的int类型转变为引用类型的呢?具体过程到底如何呢?咱们有必要通过一些反编译工具进行反编译一些,上述代码反编译后得到的代码如下:
valueOf()源码分析
从反编译的结果中我们可以看到,反编译后的代码除了添加了一个默认的无参构造外,还将原来直接赋值的方式变成了调用Integer的valueOf方法!很显然,就是在这个方法中进行类型的转换操作的!下面我们就打开valueOf这个方法的源码来一探究竟。
从源码中可以看到,valueOf方法的实现其实比较简单!我们很容易就能看出该方法的脉络,那就是如果i值在IntegerCache.low和IntegerCache.high范围之间,则返回数组中的一个对象;如果超过了这个范围,就会使用这个数值创建一个新的Integer对象并返回。
IntegerCache源码
至于具体的执行情况如何,咱们还得打开IntegerCache这个类来查看。
从上面的源码中我们可以看到,IntegerCache这个类是Integer中的一个内部类。这个类里定义了一个Integer常量缓存数组cache,这个数组可以缓存-128到high这个变量之间的所有数据。这个high值,默认是127,但是我们也可以自己设置,但必须保证最大值至少要大于等于127,同时还要保证数组的长度不会超过整数类型的最大值,因为这个数组要缓存所有的-128到high之间的值。上面源码中,第23行代码到27行的代码,就是将-128到high之间的数通过new Integer()的方式生成Integer类型的对象,并放在数组中。
valueOf再探究
接下来我们再回到valueOf方法来看一下:
可以看出,在默认情况下,100属于-128到127的范围,因此num1和num2都是使用的缓存数组中的同一个对象。而1000在缓存数组缓存的范围之外,因此是重新创建了两个Integer对象,并分别赋值给num3和num4,因此num1和num2比较时地址是相等的,而num3和num4的地址是不等的!
经过上面给大家的分析,你现在是不是已经对Integer的缓存机制有了深入的认识呢?
相关推荐HOT
更多>>如何添加Java环境变量?
要添加Java环境变量,可以按照以下步骤:并安装Java开发工具包(JDK)、找到Java安装路径、设置JAVA_HOME环境变量、添加Java可执行文件路径到PATH...详情>>
2023-05-04 11:00:56从零开始学Java之String字符串的编码
对很多小白来说,可能不明白什么是字符编码,也不知道为什么要有字符编码,所以先来给大家简要地介绍一下字符编码。详情>>
2023-05-04 10:21:02新手速来!几步带你掌握MyBatis Plus
Mybatis-Plus(简称MP)是一款Mybatis的增强工具,它是在Mybatis的基础上实现的简化开发工具。Mybatis-Plus给我们提供了开箱即用的CRUD操作、自动...详情>>
2023-04-28 10:57:09学习java需要什么基础?基础知识有哪些?
网络编程:了解基本的网络编程概念和协议,熟悉 Java 网络编程 API。建议在学习 Java 之前,先学习一些基础的编程语言,如 C 或 Python 等,这...详情>>
2023-04-28 10:41:14