如何理解Java中的自动拆箱和自动装箱?

news2024/11/26 22:18:06

个人主页:金鳞踏雨

个人简介:大家好,我是金鳞,一个初出茅庐的Java小白

目前状况:22届普通本科毕业生,几经波折了,现在任职于一家国内大型知名日化公司,从事Java开发工作

我的博客:这里是CSDN,是我学习技术,总结知识的地方。希望和各位大佬交流,共同进步 ~

一、什么是自动拆箱?

自动将基本数据类型转换为包装器类型。

Integer i = 56;//底层执行了:Integer i = Integer.valueOf(56);

数值 56 是基本数据类型 int,当赋值给包装器类型(Integer)变量的时候,触发自动装箱操作,创建一个 Integer 类型的对象,并且赋值给变量 i。

二、什么是自动装箱?

自动将包装器类型转化为基本数据类型。

int j = i; //底层执行了:int j = i.intValue();

当把包装器类型的变量 i,赋值给基本数据类型变量 j 的时候,触发自动拆箱操作,将 i 中的数据取出,赋值给 j。
 

三、为什么需要自动拆箱和自动装箱?

自动拆箱避免了手动调用 intValue()或类似方法来获取基本数据类型的值,使代码更简洁。

自动装箱允许我们将基本数据类型直接赋值给包装类对象,而不需要显式地创建对象。

自动拆箱(Auto-unboxing)和自动装箱(Auto-boxing)的主要目的是为了在基本数据类型(如int、double等)和它们的包装类(如Integer、Double等)之间实现自动转换,以简化编程和提高代码可读性。

四、在源码中的使用

我们可以直接看一下下面的这个例子:

Integer i1 = 56;
Integer i2 = 56;
Integer i3 = 129;
Integer i4 = 129;
System.out.println(i1 == i2);    // true
System.out.println(i3 == i4);    // false

输出的结果:

一个 true,一个 false 

是不是很奇怪?似乎有点匪夷所思。

但实际上,这正是因为 Integer 用到了享元模式复用对象,才导致了这样的运行结果。当我们通过自动装箱,也就是调用 valueOf() 来创建 Integer 对象的时候,如果要创建的 Integer 对象的值在 -128 到 127 之间,会从 IntegerCache 类中直接返回,否则才调用 new 方法创建。 

简单的说,如果值在(-128 ~ 127)之间,不会创建对象,而是复用"缓存"中的对象。

Integer 的 valueOf()

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

Integer 的 静态内部类 IntegerCache

private static class IntegerCache {
    static final int low = -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");
        if (integerCacheHighPropValue != null) {
            try {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 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++);
        // range [-128, 127] must be interned (JLS7 5.1.7)
        assert IntegerCache.high >= 127;
    }
    private IntegerCache() {}
}

这里的 IntegerCache 相当于,生成享元对象的工厂类,只不过名字不叫 xxxFactory 而已。这个类是 Integer 的内部类。

为什么 IntegerCache 只缓存 -128 到 127 之间的整型值呢?

在 IntegerCache 的代码实现中,当这个类被加载的时候,缓存的享元对象会被集中一次性创建好。

但是,毕竟整型值太多了,我们不可能在 IntegerCache 类中预先创建好所有的整型值,这样既占用太多内存,也使得加载 IntegerCache 类的时间过长。所以,我们只能选择缓存对于大部分应用来说最常用的整型值,也就是一个字节的大小(-128 到 127 之间的数据)。

不妨再看一个例子:

Integer a = new Integer(123);
Integer a = 123;
Integer a = Integer.valueOf(123);
  • 第一种创建方式并不会使用到 IntegerCache
  • 而后面两种创建方法可以利用 IntegerCache 缓存,返回共享的对象,以达到节省内存的目的

举一个极端一点的例子,假设程序需要创建 1 万个 -128 ~ 127 之间的 Integer 对象

使用第一种创建方式,我们需要分配 1 万个 Integer 对象的内存空间;使用后两种创建方式,我们最多只需要分配 256 个 Integer 对象的内存空间。 

文章到这里就结束了,如果有什么疑问的地方,可以在评论区指出~

希望能和大佬们一起努力,诸君顶峰相见

再次感谢各位小伙伴儿们的支持!!!

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

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

相关文章

亚运会:举办次数最多的是泰国,观众满意度衡量赛事成功情况

本文由群狼调研&#xff08;长沙第三方评估&#xff09;整理出品&#xff0c;欢迎转载&#xff0c;请注明出处。8日起至9月20日&#xff0c;杭州第19届亚运会火炬传递启动&#xff0c;杭州亚运会是放开后的首个盛会&#xff0c;亚洲的健儿齐集于此&#xff0c;同场竞技&#xf…

【C++入门】C语言的不足之处

概要 C入门主要讲的是C语言的一些不足&#xff0c;C作为补充&#xff0c;来补充C的不足之处 C的关键字有63个&#xff0c;C语言有32个&#xff08;作为了解&#xff0c;不需要专门记&#xff09; 变量的命名规则&#xff1a; 变量名必须以字母或下划线开头。变量名只能包含字…

httprunner环境变量

前言 我的上一篇文章讲了httprunner的基本介绍&#xff0c;这篇文章呢主要来给大家介绍httprunner中的环境变量。 一般来说&#xff0c;在进行实际应用的开发过程中&#xff0c;应用会拥有不同的运行环境&#xff0c;通常会有以下环境&#xff1a; 本地开发环境测试环境生产…

Flask狼书笔记 | 07_留言板

文章目录 7 留言板7.1 使用包组织代码7.2 Web开发流程7.3 使用Bootstrap-Flask7.4 Flask-Moment本地化日期和时间7.5 使用Faker生成虚拟数据7.6 Flask_DebugToolbar调试程序7.7 Flask配置的两种组织形式小结 7 留言板 这是一个简单的程序&#xff0c;涉及到的大部分是之前所学…

windows弹出交互式服务检测一键取消bat脚本

现象 脚本命令 新建一个bat文件&#xff0c;将下面的脚本拷贝进去&#xff0c;保存&#xff0c;双击即可 禁用服务&#xff1a;重启电脑的时候不会启动 停止服务&#xff1a;立即停止服务&#xff0c;马上生效的 sc config UI0Detect start disabled net stop UI0Detect

AQS同步队列和等待队列的同步机制

理解AQS必须要理解同步队列和等待队列之间的同步机制&#xff0c;简单来说流程是&#xff1a; 获取锁失败的线程进入同步队列&#xff0c;成功的占用锁&#xff0c;占锁线程调用await方法进入条件等待队列&#xff0c;其他占锁线程调用signal方法&#xff0c;条件等待队列线程进…

攻防世界题目练习——Crypto密码难度1(一)

题目目录 1. base642. Caesar3. Morse4. Broadcast5. hidden key6. [简单] 初识RSA7. 简单的LFSR8. baigeiRSA 1. base64 下载文件&#xff0c;打开是一个txt文件&#xff0c;解密工具base64解码&#xff0c;如图&#xff1a; 2. Caesar 打开文件看到字符如下&#xff1a; …

道一云·七巧对接打通金蝶云星空查询七巧表单接口与供应商新增接口

道一云七巧对接打通金蝶云星空查询七巧表单接口与供应商新增接口 数据源平台:道一云七巧 道一云七巧拥有强大的自定义表单设计工具&#xff0c;并配置工作流程&#xff0c;通过流程智能流转&#xff0c;打通各个业务场景中的审批、协作环节&#xff0c;包含数据采集单、任务单…

strlen函数使用与模拟实现【进阶版】

strlen函数使用与模拟实现 1.strlen函数介绍 资源来源于cplusplus网站 翻译过来的大致意思就是&#xff1a; 获取字符串长度 2.strlen的使用 int main() { //strlen - 求字符串长度的 //字符串的结束标志是\0 //strlen统计的是\0之前出现的字符的个数 //基本功能 char arr[]…

【送书活动】全网超50万粉丝的Linux大咖良许,出书了!

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

母婴品牌的小红书投放策略有哪些,投放总结

最近有很多人想知道达人投放的一些相关知识&#xff0c;我们立马捕捉到了大家对这一干货内容的感兴趣程度&#xff0c;今天就来为大家分享下&#xff0c;母婴品牌的小红书投放策略有哪些&#xff0c;投放总结&#xff01; 什么是达人投放? 达人投放是一种常用于社交媒体营销的…

异步FIFO项目 UVM验证

文章目录 前言一、异步FIFO仿真过程1、异步FIFO设计2、UVM验证 二、脚本文件编写三、编译错误 前言 2022.11.15 记录自己开始使用UVM仿真异步FIFO项目 一、异步FIFO仿真过程 1、异步FIFO设计 首先对编写的异步FIFO设计代码进行验证&#xff0c;写了一个test.v文件 &#xff…

docker概念、安装与卸载

第一章 docker概念 Docker 是一个开源的应用容器引擎。 Docker 诞生于2013年初&#xff0c;基于 Go 语言实现&#xff0c;dotCloud 公司出品&#xff0c;后改名为 Docker Inc。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发…

Python的命名空间和作用域

所谓作用域就是指变量名/对象名在多大范围内是可见的/有效的&#xff0c;一个变量名既不能作用域太大&#xff0c;这样会引发广泛的命名冲突&#xff0c;也不能太小&#xff0c;这样很难实现变量的共享&#xff0c;所以一般都有多层次的作用域。一个层次的作用域&#xff0c;在…

WebGL 同时使用多幅纹理

目录 前言 ​编辑 示例代码 颜色矢量的分量乘法来计算两个纹素最终的片元颜色 注册事件响应函数&#xff1a;loadTexture&#xff08;&#xff09;&#xff0c;最后一个参数是纹理单元编号。 请求浏览器加载图像&#xff1a; 配置纹理&#xff1a;loadTexture&#xff0…

linux 安装Docker

# 1、yum 包更新到最新 yum update # 2、安装需要的软件包&#xff0c; yum-util 提供yum-config-manager功能&#xff0c;另外两个是devicemapper驱动依赖的 yum install -y yum-utils device-mapper-persistent-data lvm2 # 3、 设置yum源 yum-config-manager --add-repo h…

基于SSM的汽车养护管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

谈论浏览器内核

浏览器内核是指浏览器使用的渲染引擎&#xff0c;用于解析并显示网页的内容。主要有以下几种浏览器内核&#xff1a; Trident&#xff08;IE内核&#xff09;&#xff1a;由Microsoft开发&#xff0c;被用于Internet Explorer浏览器。目前已经被Edge取代。 Gecko&#xff1a;…

并发内存池(C++)

项目简介 这个项目是实现了一个高效的并发内存池。它的原型的goggle的一个开源项目tcmalloc&#xff0c;即thread-cache malloc&#xff08;线程缓存的malloc&#xff09;&#xff0c;实现了高效多线程的内存管理&#xff0c;可实现对系统提供的内存分配函数malloc和free的替代…

调教 文心一言 生成 AI绘画 提示词(Midjourney)

文章目录 第一步第二步第三步第四步第五步第六步第七步第八步 文心一言支持连续对话 我瞎玩的非专业哈哈 第一步 你好&#xff0c;今天我们要用扩散模型创建图像。我会给你提供一些信息。行吗? 第二步 这是Midjourney的工作原理:Midjourney是另一个基于ai的工具&#xff0c;能…