剖析valueOf方法,深入探究Integer缓存实现机制

news2024/11/19 14:34:48

一. 问题展现

我们在面试的时候,面试官经常会给面试者洒出一些迷雾,用来迷惑面试者,这时往往就需要面试者掌握底层源码,才能对问题进行较好的回答。接下来壹哥就以Integer的缓存数组为例,通过分析其源码来教会大家该如何应对带有迷惑性的面试。

为了讲解清楚,壹哥给大家设计了一段代码如下,我们可以运行下面这段代码:

 public class Test{
     public static void main(String[] args){  
         Integer num1 = 100;
         Integer num2 = 100;
         System.out.println(num1==num2);
         
         Integer num3 = 1000;
         Integer num4 = 1000;
         System.out.println(num3==num4);
    }
 }

上面这段代码中,其实就涉及到了关于Integer缓存机制相关的一些面试题,比如面试官会问我们,”你知道Integer的缓存机制吗“,”Integer.valueOf()方法的源码你熟悉吗?“,”int和Integer的区别有哪些“......

二. 结果分析

上面代码输出的结果应该是:

true
false

上面代码中有两个不一样的输出结果,本来明明以为是一样的结果,其实却不然!为什么这两个输出的结果一个是true,另一个却是false呢?

其实这里,num1和num2是在Integer的缓存数组中直接获取的整型缓存对象!而num3和num4却都是在直接new出来的Integer对象。至于为什么会这样,壹哥会结合Integer的源码对这个问题进行详细说明。

三. 源码解析

    • 反编译结果

表面上看,上面的代码中都是把int类型的数值赋给了一个Integer引用类型。但是我们知道,一个基本的数据类型赋值给引用类型会进行装箱操作。那么Integer类又是如何将一个基本的int类型转变为引用类型的呢?具体过程到底如何呢?咱们有必要通过一些反编译工具进行反编译一些,上述代码反编译后得到的代码如下:

public class TestInt{
    public TestInt(){
    }
      
    public static void main(String args[]){
        Integer num1 = Integer.valueOf(100);
        Integer num2 = Integer.valueOf(100);
        System.out.println(num1 == num2);
             
        Integer num3 = Integer.valueOf(1000);
        Integer num4 = Integer.valueOf(1000);
        System.out.println(num3 == num4);
    }
}
    • valueOf()源码分析

从反编译的结果中我们可以看到,反编译后的代码除了添加了一个默认的无参构造外,还将原来直接赋值的方式变成了调用Integer的valueOf方法!很显然,就是在这个方法中进行类型的转换操作的!下面我们就打开valueOf这个方法的源码来一探究竟。

 public static Integer valueOf(int i) {
     if (i >= IntegerCache.low && i <= IntegerCache.high)
         return IntegerCache.cache[i + (-IntegerCache.low)];
     return new Integer(i);
 }

从源码中可以看到,valueOf方法的实现其实比较简单!我们很容易就能看出该方法的脉络,那就是如果i值在IntegerCache.low和IntegerCache.high范围之间,则返回数组中的一个对象;如果超过了这个范围,就会使用这个数值创建一个新的Integer对象并返回。

    • IntegerCache源码

至于具体的执行情况如何,咱们还得打开IntegerCache这个类来查看。

private static class IntegerCache {
        static final int low = -128;//缓存数组最小值设置为-128
        static final int high;
        static final Integer cache[];
        static {
            // high value may be configured by property
            int h = 127;
            //获取虚拟机参数中设置的上限值
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            //判断如果这个值不是空,则把这个值和127比较取大值赋给high,同时对数组的范围进行
            //了限制保证数组的长度不能超过int类型的最大值
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);//获取127和设置的较大值
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);//判断是否超过整形最大值
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;
            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);//把-128到high的数据一一赋进缓存数组中
            assert IntegerCache.high >= 127;
        }
        private 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的地址是不等的!

四. 知识扩展

    • 修改high值

如果我们设置了high值是1000,应该看到num3==num4的结果也应该是true。我们可以在下面验证一下,这里要通过虚拟机参数设置high值,以eclipse为例,具体设置方法见下图:

    • 再次执行

如上图,对high参数设置之后,high值变为了1000,我们点击run按钮重新运行,结果如下图:

可以看出,结果如咱们所料,此时两个结果均为true!

五. 总结

经过上面壹哥给大家的分析,你现在是不是已经对Integer的缓存机制有了深入的认识呢?最后咱们再把上述内容总结一下,看看该如何清晰地回答面试官的问题吧,对于这类面试题,我们可以这么回答:

在我们给Integer对象赋值时,其实是调用了Integer类的valueOf这个静态方法,而这个静态方法使用了Integer类中的IntegerCache内部类。
在IntegerCache这个内部类中存在一个Integer对象的缓存数组,这个数组中默认缓存了从-128到127的所有Integer对象。
当我们所赋的值在这个范围之间的时候,会直接从数组中获取Integer的缓存对象,因此两次100都是同一个对象。但是1000超出了这个范围,就会重新创建一个Integer对象,因此两次1000不是同一个对象。

至此,面试官的问题已经回答清楚了。如果你还记得住该如何设置high的最大值,也可以把最大值的设置过程给面试官讲讲,这个就属于锦上添花的回答了。

以上就是壹哥对Integer缓存机制面试题的分析过程,现在你知道该怎么去回答这个面试题了吗?欢迎大家在评论区给壹哥留言,说说你的感悟或疑惑吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/159646.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux串口测试例程

嵌入式Linux开发过程中&#xff0c;进行Linux串口测试&#xff0c;需要针对串口进行回环测试或者指定串口接收一定的数据或者指定串口发送一定的数据使用该测试用例很快验证硬件串口的稳定性和正确性。使用代码连接如下Linux串口测试例程&#xff0c;进行Linux串口测试&#xf…

爬虫逆向之字体反爬(二)、镀金的天空-字体反爬-2

趁热打铁来写字体反爬的第二篇&#xff0c;首先是题目 网页上显示的不是常规的数字&#xff0c;源码里面也是一些汉字 虽然看上去很乱&#xff0c;但是仔细观察还是能发现一些规律&#xff0c;比如&#xff1a;长 对应 2&#xff0c;思对应 1 所以这里的解题思路&#xff0c;也…

基于Python实现四大名著章节标注汉语拼音

起因很单纯&#xff0c;就是给我1年级小豆包的女儿标注三国和西游章节的汉语拼音&#xff0c;我女儿每天都朗读 &#xff0c;结果有很多字不认识&#xff0c;我爱人居然让我给标记不认识的完了手动注音......我勒个去......身为程序员的我怎么能忘记用程序实现呢&#xff0c;特…

再次战胜人类:Meta AI推出首款可以忽悠人的AI模型

文&#xff5c;ShonaCicero&#xff0c;是Meta AI提出的能够在『强权外交』游戏中超越人类的AI模型。它凭借自己"忽悠"人的能力&#xff08;模拟谈判与合作&#xff09;&#xff0c;成为游戏里的顶级高手。AI模型连外交这活儿都能得心应手了&#xff1f;没错&#xf…

【尚硅谷】Java数据结构与算法笔记07 - 排序算法

文章目录一、排序算法简介二、排序的分类三、冒泡排序3.1 基本介绍3.2 算法图解3.3 代码实现四、选择排序4.1 基本介绍4.2 思路分析4.3 算法图解4.4 代码实现五、插入排序5.1 基本介绍5.2 思路分析5.3 算法图解5.4 代码实现六、希尔排序6.1 简单插入排序存在的问题6.2 基本介绍…

知识点查漏补缺

目录谷粒商城知识点补充前言1 java8新特性之lambda表达式1.1 为什么使用1.2 从匿名类到Lambda的转换1.3 语法总结2 Stream API2.1 概述2.2 创建2.2.1 通过集合2.2.2 通过数组2.2.3 通过Stream的of()2.2.4 创建无限流2.3 中间操作2.3.1 筛选与切片1)、filter2)、limit3)、skip(n…

【数据结构】—— Java实现队列和循环队列

队列与循环队列一、队列1.概念2.队列的使用3.队列的模拟实现二、循环队列1.基本概念2.代码实现一、队列 1.概念 队列&#xff1a;是允许在一端进行插入操作&#xff0c;而在另一端进行删除操作的线性表。 队列是一种先进先出的&#xff08;First In First Out&#xff09;的…

商场楼层分布图用什么软件做,高效、便捷的商场二三维地图绘制平台

现在的很多大型购物商场占地面积较大&#xff0c;商品种类繁多&#xff0c;如果没有商场导航&#xff0c;会导致新顾客难以找到想要的店铺和商品&#xff0c;那么大型购物商场导航怎么实现呢&#xff1f;电子地图作为大家最喜闻乐见的高效应用形式&#xff0c;在商业应用中&…

C生万物 | 函数的讲解与剖析【内附众多案例详解】

&#x1f451;作者主页&#xff1a;Fire_Cloud_1 &#x1f3e0;学习社区&#xff1a;烈火神盾 &#x1f517;专栏链接&#xff1a;万物之源——C 一起来学习函数吧&#xff01;一、函数是什么&#xff1f;二、C语言中函数的分类1、库函数2、自定义函数【⭐⭐⭐】三、函数的参数…

【Linux学习】vim指令集(一)

Linux的最高境界 1、背景 vim是一款多模式的文本编辑器&#xff0c;兼容所有的vi语法&#xff0c;其有多种操作模式&#xff0c;每种模式可以互相切换。vim的安装指令如下所示&#xff1a; yum install -y vim2、vim编辑器的相关指令 常用的vim模式有命令模式、插入模式、底…

Vue项目大概目录介绍

后端,自己学习做个记录.实话是看不懂全靠抄. 这是一个刚建好的Vue项目 node_modules:整个项目用到的依赖文件 public--->favicon.ico:Vue的图标 public--->index.html:可以理解为首页入口,模板页,开发的时候用不到,Vue是个单页面应用,开发也用不到 src:好比项目的源码…

智云通CRM:阻挡客户拜访的三个因素,你中了几个?

拜访客户为什么会迟迟不行动&#xff0c;一般有三个因素&#xff0c;它们分别是“没有主动性”“证明自己的价值需要时间”“我很不专业&#xff0c;需要学习”&#xff0c;因为这三个因素都在诉说一件事——“我需要准备”。智云通CRM统计常见的情形如下。 “我刚刚从事这个…

nginx反向代理、负载均衡、动静结合

目录前言nginx是什么&#xff1f;一.启动异常1.80端口被占用① 关掉占用端口② 修改 nginx.conf 文件2.启动nginx并测试是否启动成功① 启动② 测试 电脑ip 你自己在nginx.conf设置的端口二.应用场景之负载均衡三.应用场景之反向代理1.正向代理和反向代理的区别2.配置反向代理…

Linux常用命令——wget命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) wget Linux系统下载文件工具 补充说明 wget命令用来从指定的URL下载文件。wget非常稳定&#xff0c;它在带宽很窄的情况下和不稳定网络中有很强的适应性&#xff0c;如果是由于网络的原因下载失败&#xff0c;…

一款ARPG游戏是如何搭建云真机系统的

随着业内对“工业化”认知的不断提升&#xff0c;越来越多的UWA用户通过UWA Pipeline的各项功能&#xff0c;为项目研发提供了极大的助力。其中的自动化测试与GOT Online性能测评的结合&#xff0c;帮助项目组在每个“测试-反馈”周期内&#xff0c;在大批量真机设备上实现项目…

Linux——信号知识归纳(下)

目录 一.进程状态 二.信号捕捉时机与流程 三.sigaction函数 四.SIGCHLD信号 一.进程状态 linux将进程的状态分为用户态&#xff08;user mode&#xff09;和内核态&#xff08;kernel mode&#xff09;。 内核态时CPU执行代码不受任何限制&#xff0c;而用户态会做代码安…

MRP的库存供应天数(StckDS)和收货供应天数(RDS)

我们在MD07里面&#xff0c;可以看到三个天数&#xff1a; 1、库存可供应天数(StckDS) 2、第一次日供应量收货(RDS 1) 3、第二接货日期的收货(RDS 2) 而且信号灯的显示就是按照这三个天数来进行设置的 我们以15000047这个物料为例&#xff0c;来看下这三个数是怎么计算的 …

Java集合全解【完整版】

文章目录01 初识集合> 集合是什么&#xff1f;为什么要用集合&#xff1f;> 集合的框架体系02 Collection接口> Collection接口常用方法> Collection接口遍历元素&#xff1a;使用Iterator&#xff08;迭代器&#xff09;> Collection接口遍历元素&#xff1a;增…

那个叫郭不戳的博主去哪了--回归篇

文章目录那个叫郭不戳的博主去哪了--回归篇所以你究竟去哪了&#xff1f;有没有好的面试经验啊工作方面怎么样啊卷不卷总结那个叫郭不戳的博主去哪了–回归篇 消失了三个月&#xff0c;今天开始正式回归。一大早打开CSDN看到好多消息&#xff0c;首先谢谢大家对我的认可。接下来…

基于微信小程序云开发的医院体检预约小程序源码,医院体检预约小程序源码,实现体检预约管理、体检预约凭证、预约数据查看导出 版权申诉

功能介绍 对于医院体检科室和体检机构而言&#xff0c;每天的体检人数分布也不太均衡&#xff0c;若很多人集中在 某些天体检&#xff0c;会出现「医生强度大、体检人排队久」的问题。采用体检预约小程序进行体检预约数管理&#xff0c;体检人可预约到更广的日期范围、更精准的…