//自动装箱

Integer numNew = 1;

}

javap 一看究竟:

行,确实是自动装了,咱们赶场,看拆箱去。

2. Integer拆箱 ,将一个引用类型 Integer  的对象 转换 为对应的  基本数据  int 类型的值  (Integer -> int) :

核心方法 :  Integer.intValue();

手动拆箱示例:

Integer numNew = 1;

//手动拆箱

int num = numNew.intValue();

是的,可以手动,但是没必要。因为 自动拆箱在java 5里面引入了。

Integer numNew = 1;

//自动拆箱

int num = numNew;

一看究竟,好的确实是拆了 :

看到这,看客们应该对装、拆箱有了一些认识了,事不宜迟,我们进入大家最喜欢的源码环节:

Integer装箱方法,我们刚刚提到了,通过javap 分析也能知道

就是   Integer.valueOf();

那么我们直接到源码里面搜索 valueOf ,定位到我们需要看的源码部分:

英文水平比较好的看客,看到这个图,其实心里面已经透亮了。

而跟我一样水平的看客应该也是存在的,那么咱们看下中文翻译(关键部分):

如果需要,通常应优先使用此方法。

构造函数{@link#Integer(int)},因为这个方法很可能通过缓存频繁请求的值。

此方法将始终缓存-128到127范围内的值,包含,并且可能缓存此范围之外的其他值。

自1.5

注释简洁明了, 1.5引入; 范围 -128~127 ; 允许配置范围; 优先调用该方法;

结合实例,开始debug,分析源码:

进入断点, 在编译的时候自动装箱,调用了方法**.valueOf()  😗*

这里是说,符合if条件的,那么就 返回 IntegerCache 里面的 cache 值 , cache(缓存),那就是说,符合条件的,从缓存里面拿出来就好。

那么不符合if条件的, 使用new ,那么意思就是单独处理了。

结论:

判断是否在-128~127区间内,是则返回相应的对象引用,不是则返回一个新实例化的对象。

if 条件 :

if (i >= IntegerCache.low && i <= IntegerCache.high)

IntegerCache 是什么? 判断范围是 IntegerCache的 low值和high值之间。

IntegerCache 其实就是 存放箩筐的 临时仓库 , 也就是可以理解为缓存池。

还记得我们的临时仓库存放箩筐的规则是什么吗?  箩筐编码必须在 范围 -128~ 127 之间, 也就是 low值和high值之间  。

简单点进去IntegerCache的源码看一眼:

可以看到关于范围值的获取 , 大致说的就是默认是-128~127 , 但是high值也许是通过配置调整过的。

通过-XX:AutoBoxCacheMax=size修改   或者  通过java.lang.Integer.IntegerCache.high设置最大值

这个 IntegerCache 其实在Integer里是 静态内部类。

初始化的时候,就会对范围内的值进行逐个进行处理,放到 Integer cache[] 缓存数组里面 。 也就是说,箩筐、仓库应用的都有。

这么一来,当我们使用的时候,自动装箱,范围内的就是从缓存仓库里面取就完事了,够快。

注意点  一


Integer值的 比较

既然我们都看到这里了, 也注意到了这个范围的概念。

显然看客们心里必然有想法, 就是范围外的值,装箱后, 不在缓存池里。

使用 new , new大家熟悉吧,用了new 意味着 重新编辑了一个箩筐(分配内存)。

直接看代码:

值比较示例 1:

值比较示例2:

使用“==”比较两个包装类引用时,比较的是指向的引用地址。

两个值 都是 13 , 都在范围 -128 ~ 127之间,  使用  ==  符合比较, 相同,true 。

两个值 都是 130 , 都不在范围 -128 ~ 127之间,  使用  ==  符合比较, 相同,false。

为什么? 刚才看了源码了,

那么既然知道了这个问题, 我们怎么去比较呢?

1. 范围内 可以使用 == , 范围外 先转为int数值再比较。 干脆点,也就是可以理解为,统统都使用 .intValue再比较。

意思就是利用拆包,转化成 int 类型数值比较, 这样 使用 == 符合就非常正确。

2. 是不是觉得上面说的方式好麻烦?  是的,Integer的作者也知道看客们嫌麻烦,所以Integer重写了 equal方法 :

可以看到,里面也是进行了intValue() ,所以我们可以放心使用 equal去进行值比较。

注意点  二


小心 null 导致 NPE异常

因为 Integer 是包装类,那么接收值的时候 存在null的情况。 如果是null,还去使用的话,那么就会出现空指针 NPE异常。

注意点 三


该篇文章是以 Integer为例做的介绍, 千万不要以为 其他包装类 Double 、Float 也是这个逻辑 ,自动装箱拆箱也是这些 缓冲池、范围等等。

不是 ! 不是 !  不是 !

其他的包装类人家虽然也会自动装拆, 但是 ! 逻辑不一样!

举例 提醒:

为什么不是 true ? 因为人家的valueOf() 不一样!! 所以前往别把Integer的知识,完全往别的包装类上面理解。

可以看一眼,Double的 valueOf() :

为什么Double不做缓存池? 不弄箩筐了吗? 不弄临时仓库了吗? 是穷吗?弄不起?

你细想, 因为是Double ,光是 1-2之间, 1.1,1.2,1.3 … 1.11 ,1.12 这些精度, 你想想如果弄缓冲池,缓存的量多么恐怖。

再看一眼Boolean的 valueOf()  :

这Boolean 不是true就是false ,所以人家啥缓存不缓存的,啥范围的都不需要考虑了,之间就给 定死判断返回得了。

扯远了, 要想了解其他包装类的一些知识,可以参考我本文上面的了解Integer过程,自己也去看一看代码~

上面很多东西说的都是装箱,那么我们继续说说拆箱。

上边内容里有简单提到, 拆箱, 以Integer为例子来说,就是intValue(),转化成为int类型数据进行使用。

使用起来没啥问题,intValue源码也简单直接:

那么我们也举一些平时也许会使用到的示例来加深理解:

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

终极手撕架构师的学习笔记:分布式+微服务+开源框架+性能优化

image

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

终极手撕架构师的学习笔记:分布式+微服务+开源框架+性能优化

[外链图片转存中…(img-oZK8k6VZ-1712578049350)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐