Java 中的自动装箱和拆箱详解

2023-11-19

目录

1、Java 中的自动装箱

2、Java 中的自动拆箱

3、自动装箱和拆箱总结  

4、在Java中怎样避免自动装箱和拆箱?


1、Java 中的自动装箱

        自动装箱是 Java 编译器在基本类型和它们对应的包装类之间进行的自动转换。例如,将 int 类型转换为 Integer 类型,将 double 类型转换为 Double 型等等。如果转换以相反的方式进行,则称为开箱。// 包装类和基本数据类型的相互转换

        下面是一个最简单的自动装箱例子:

Character ch = 'a';

        例如,下面的代码:

List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
    li.add(i);

        尽管将 int 值作为基本类型而不是 Integer 对象添加到 li 列表,但是代码仍然可以编译。这里 li 是一个 Integer 对象的列表,而不是 int 值的列表,为什么 Java 编译器不会发出编译时错误呢?编译器之所以不会产生错误,是因为它从 i 创建了一个 Integer 对象,并将该对象添加到 li 列表。因此,编译器在运行时实际是将前面的代码转换为以下代码:

List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
    li.add(Integer.valueOf(i));

        在以下情况下,Java 编译器会对基本类型的值进行自动装箱:

  1. 把基本类型的值作为参数传递给需要相应包装类的对象的方法。
  2. 基本类型的值赋给相应包装类的变量。

2、Java 中的自动拆箱

        接下来,思考一下下边的方法:

public static int sumEven(List<Integer> li) {
    int sum = 0;
    for (Integer i: li)
        if (i % 2 == 0)
            sum += i;
        return sum;
}

        求余运算符 (%) 和一元运算符 (+=) 并不适用于 Integer 对象,但 Java 编译器在编译该方法时却不会产生任何错误,因为在调用 intValue() 方法时,Java 会将 Integer 转换为 int:

public static int sumEven(List<Integer> li) {
    int sum = 0;
    for (Integer i : li)
        if (i.intValue() % 2 == 0) //拆箱操作
            sum += i.intValue();
        return sum;
}

        将包装类型(Integer)的对象转换为其对应的基本类型(int)称为拆箱。在以下情况下,Java 编译器会对包装类型的值进行自动拆箱:

  1. 把包装类型的值作为参数传递给需要相应基本类型的值的方法。
  2. 把包装类型的值赋值给相应基本类型的变量。

        下边的例子展示了拆箱是如何工作的:

import java.util.ArrayList;
import java.util.List;

public class Unboxing {

    public static void main(String[] args) {
        Integer i = new Integer(-8);

        // 1. 通过方法调用进行拆箱
        int absVal = absoluteValue(i);
        System.out.println("absolute value of " + i + " = " + absVal);

        List<Double> ld = new ArrayList<>();
        ld.add(3.1416);    // Π 通过方法调用自动装箱。

        // 2. 通过赋值进行拆箱
        double pi = ld.get(0);
        System.out.println("pi = " + pi);
    }

    public static int absoluteValue(int i) {
        return (i < 0) ? -i : i;
    }
}

        该程序会打印以下内容:

absolute value of -8 = 8
pi = 3.1416

3、自动装箱和拆箱总结  

        自动装箱和拆箱可以让开发人员编写更加清晰的代码,使代码更加易于阅读。下表列出了基本类型及其对应的包装类,Java 编译器会使用它们进行自动的装箱和拆箱:

基本类型 包装类型
boolean Boolean
byte Byte
char Character
float     Float
int     Integer
long     Long
short     Short
double     Double

        自动装箱和拆箱的实现是通过 Java 编译器在编译时进行的。具体来说,Java 编译器会将自动装箱和拆箱操作转换为对应的方法调用,以实现基本数据类型和包装类型之间的转换。

        在自动装箱时,编译器会自动调用对应的包装类型的 valueOf() 方法来将基本数据类型转换为对应的包装类型。例如,将 int 类型的变量 i 转换为 Integer 类型的变量 obj,编译器会自动调用 Integer.valueOf(i) 方法。

        在自动拆箱时,编译器会自动调用对应的包装类型的 xxxValue() 方法将包装类型转换为基本数据类型。例如,将 Integer 类型的变量 obj 转换为 int 类型的变量 i,编译器会自动调用 obj.intValue() 方法。

        需要注意的是,在进行自动装箱和拆箱的过程中,编译器会生成一些额外的代码,因此可能会对性能产生一定的影响。因此,在对性能要求较高的场景下,应尽量避免使用自动装箱和拆箱。

4、在Java中怎样避免自动装箱和拆箱?

        (1)使用基本数据类型

        尽可能地使用基本数据类型,而不是对应的包装类型。基本数据类型的数据存储在栈中,而包装类型的对象存储在堆中,因此基本数据类型的操作比包装类型的操作更加高效。

        (2)使用静态常量

        对于常用的数值,可以使用静态常量来避免自动装箱的开销。例如,使用如下代码定义一个静态常量:

public static final int MAX_VALUE = 100;

        这样就可以在代码中直接使用 MAX_VALUE,而不需要使用 Integer.valueOf(MAX_VALUE)。

        (3)使用 StringBuilder 或 StringBuffer

        在字符串拼接时,应该使用 StringBuilder 或 StringBuffer,而不是字符串连接符 “+”。因为字符串连接符会导致自动装箱的开销,而 StringBuilder 或 StringBuffer 可以避免这个问题。

        例如,将两个字符串连接起来,可以使用如下代码:

String str1 = "hello";
String str2 = "world";
StringBuilder sb = new StringBuilder();
sb.append(str1).append(str2);
String result = sb.toString();

        通过上述方法,可以有效地避免自动装箱和拆箱对程序性能的影响。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 中的自动装箱和拆箱详解 的相关文章

  • 彻底理解coookie、session、token

    一 发展史 1 很久很久以前 web基本上就是文档的浏览而已 既然是浏览 作为服务器 不需要记录谁在某一段时间里都浏览了什么文档 每次请求都是一个新的HTTP协议 就是请求加响应 尤其是我不用记住是谁刚刚发了HTTP请求 每个请求对我来说都
  • strictfp关键字

    strictfp的意思是FP strict 也就是说精确浮点的意思 在Java虚拟机进行浮点运算时 如果没有指定strictfp关键字时 Java的编译器以及运行环境在对浮点运算的表达式是采取一种近似于我行我素的行为来完成这些操作 以致于得
  • List接口及其实现类

    List接口 鉴于Java中数组用来存储数据的局限性 我们通常使用List替代数组 List集合类中元素有序 且可重复 集合中的每个元素都有其对应的顺序索引 List容器中的元素都对应一个整数型的序号记载其在容器中的位置 可以根据 序号存取
  • 文件上传优化

    文件上传优化 文件的名称需要优化 服务端 保存的文件名称如果固定 那么最终会导致服务器硬盘 只会保留一个文件 对上传的文件名称优化 System currentTimeMillis new Random nextInt 1000000 jp
  • JavaSE + bluecove 蓝牙连接

    最近公司准备将旧系统的 NET部分翻版 项目除了有后台的还有个与设备对接的客户端用蓝牙连接的 所有这周对相关技术做了一个验证 搜了一下Java 蓝牙相关信息 我去资料也太少了 少也就算了连bluecove库也是有问题的 经过艰难的查找 最终
  • 【Java 多线程 3】线程池2

    一 线程池简介 线程池是一种多线程处理形式 处理过程中将任务添加到队列 然后在创建线程后自动启动这些任务 线程池线程都是后台线程 每个线程都使用默认的堆栈大小 以默认的优先级运行 并处于多线程单元中 如果某个线程在托管代码中空闲 如正在等待
  • 哪吒社区 - 风火轮计划

    目录 风火轮计划 全新起航 风火轮计划内容 一 Java零基础入门 二 Java基础教程系列 三 SpringBoot系列教程 加入方式 1 连续七天参与Java技能树每日打卡活动 2 发表一篇标题为 哪吒社区Java技能树 的学习博客 记
  • java中CompletableFuture异步编程详解以及实践案例

    文章目录 一 CompletableFuture的使用 1 创建CompletableFuture的方式 2 获得异步执行结果 3 对执行结果进行处理 4 对执行结果进行消费 5 异常处理 6 两组任务按顺序执行 7 两组任务谁快用谁 8
  • JAVA基础:线程池的使用

    目录 1 概述 2 线程池的优势 2 1 线程池为什么使用自定义方式 2 2 封装的线程池工具类有什么好处 3 线程池的七大参数 3 线程池的创建 3 1 固定数量的线程池 3 2 带缓存的线程池 3 3 执 定时任务 3 4 定时任务单线
  • Idea快捷键大全(Windows)

    一 知道类名查找类 1 Ctrl Shift Alt N 2 双击Shift 二 查找类中所有方法 Ctrl F12 三 快速查找类或方法在整个项目中的位置 按住Ctrl键再点击类或方法会出现所有用到过的文件对象
  • 如何优雅的打印数组

    如何优雅的打印数组 以下文章来源于沉默王二 作者沉默王二 https mp weixin qq com s 20s0XSsdUE2qJDP4OtM rw 在 Java 中 数组虽然是一个对象 但并未明确的定义这样一个类 因此也就没有覆盖 t
  • Java的运算符

    目录 一 什么是运算符 二 算术运算符 1 基本四则运算符 加减乘除模 2 增量运算符 3 自增 自减运算符 三 关系运算符 四 逻辑运算符 重点 1 逻辑与 2 逻辑或 3 逻辑非 4 短路求值 五 位运算符 1 按位与 2 按位或 3
  • Java内存分配介绍

    Java的内存分配主要有三个位置 方法区 就是字节文件 存储未运行的代码 栈内存 当方法运行的时候 则在栈内存中存储 堆内存 当方法新生成对象的时候 或者新产生出局的时候将在堆内存中存储 方法区 字节文件加载时进入的内存 存储的就是编写成功
  • 【Java知识点详解 8】缓存

    Java学习路线推荐 Java基础教程系列 SpringBoot精品推荐 Spring Boot基础教程 简介 Java领域优质创作者 CSDN哪吒公众号作者 Java架构师奋斗者 扫描主页左侧二维码 加入群聊 一起学习 一起进步 欢迎点赞
  • Java 高级语法学习笔记(基础)

    目录 反射机制 Class 类 类初始化 类加载 类的生命周期 七大阶段 1 加载 接入 class文件 2 验证 连接 linking 的第一阶段 为了安全 3 准备 分配内存及初步初始化 4 解析 字符翻译成引用阶段 5 初始化 代码正
  • Java之StringUtils的常用方法

    StringUtils 方法的操作对象是 Java lang String 类型的对象 是 JDK 提供的 String 类型操作方法的补充 并且是 null 安全的 即如果输入参数 String 为 null 则不会抛出 NullPoin
  • 内部类详解

    目录 一 什么是内部类 二 内部类的划分 2 1 实例内部类 2 2 静态内部类 2 3 局部内部类 2 4 匿名内部类 一 什么是内部类 定义 当一个事物的内部 还有一个完整的结构进行描述 而这个内部的完整的结构又只为外部事物提供服务 那
  • 编码问题

    编码 字符 gt 字节数组 解码 字节数组 gt 字符 编码 String str 你好 byte bus str getBytes UTF 8 解码 String str1 new String bus UTF 8 System out
  • Java 简单修饰符补充学习笔记(基础)

    前言 顾名思义 这里是补充修饰符的学习笔记 通配符 顾名思义即可 const 常变量修饰符 首先const是constant 恒定不变的 的缩写 const 就是描述变量为常量的修饰符 关键字 或者说 const 是定义常变量的关键字 用
  • Java 之 认识String类

    目录 一 String类的重要性 二 常用方法 1 字符串构造 2 String对象的比较 3 字符串查找 4 转化 5 字符串替换 6 字符串拆分 7 字符串截取 8 其他操作方法 9 字符串的不可变性 10 字符串修改 三 String

随机推荐

  • GAN数学原理及代码实现

    GAN generator 和discriminator 生成式对抗网络 Generative Adversarial Networks GAN 包括生成器 generator 和判别器 discriminator 生成器 generato
  • springboot+mybatis+druid 多数据源整合

    前言 在上一篇文章里面我们进行了spring boot 和 mybatis 的整合 springboot整合mybatis使用druid数据源 文中是使用的单数据源 因为项目中有很多需要用到多数据源的场景 比如主从同步 读写分离 或者业务库
  • Pandas基本操作总结 excel读取和数据清洗

    1 读取表格 df pd read excel 目标文件路径 skiprows 要跳过的行数 指定读取表格时要跳过前面空行的行数 2 筛选某列不是空值的所有行 df loc df 某列 notnull 筛选某列不为空值的所有行 筛选行后选取
  • docker使用常用基础命令详解版

    文章目录 Docker基本命令 1 查看docker信息 version info 2 对image的操作 search pull images rmi history 3 启动容器 run 4 查看容器 ps 5 保存对容器的修改 com
  • Scala>scala类型判断

    文章目录 类型判断 isInstanceOf asInstanceOf getClass和classOf 类型判断 有时候 我们设计的程序 要根据变量的类型来执行对应的逻辑 在scala中 如何来进行类型判断呢 有两种方式 isInstan
  • python——lambda函数

    lambda 表达式 又称匿名函数 常用来表示内部仅包含 1 行表达式的函数 如果一个函数的函数体仅有 1 行表达式 则该函数就可以用 lambda 表达式来代替 name lambda list 表达式 其中 定义 lambda 表达式
  • nacos配置中心链接超时问题:java.net.ConnectException: no available server, currentServerAddr

    nacos配置中心链接超时问题 java net ConnectException no available server currentServerAddr 从异常信息来看 是与nacos链接异常导致 可能是因为服务器网络的问题 解决 重
  • Web前端开发概述

    Web World Wide Web 全球广域网 是指一种基于互联网的信息系统 通过超文本链接将全球各地的文档 图像 视频等资源相互关联起来 并通过Web浏览器进行交互浏览和访问 Web的发展使得人们可以方便地获取和共享各种类型的信息 成为
  • 异步接口调用

    http的异步调用 package com example asyncmethod import com fasterxml jackson annotation JsonIgnoreProperties JsonIgnorePropert
  • Babelfish【map函数】

    题目链接 这道题用哈希可以做 但是这道题的输入要求太过于繁琐 所以我直接上map稍微好弄些 这道题讲真更多的考察的是字符串的输入问题 看下代码就会明白的 完整代码 include
  • QItemDelegate和 QStyledItemDelegate的区别

    为使用方便 从 4 4开始 Qt 提供了另外的基于组件的子类 QItemDelegate和 QStyledItemDelegate 默认的委托是 QStyledItemDelegate 二者的区别在于绘制和向视图提供编辑器的方式 QStyl
  • 基于用户协同过滤(User-CF)的推荐算法

    基于用户协同过滤 User CF 的推荐算法 User CF的推荐实例 在学校生活的时候 新生开学都会问同专业的师兄师姐 我要买什么书 我要怎么安排作息 等相似的问题 此时师兄师姐就会依着他们的专业和偏好做一些推荐 这就是现实中个性化推荐具
  • KEIL5报 core_cm4.h(169): error:错误解决办法

    KEIL4的工程转到KEIL5上面出现 Core core cm4 h 169 error 5 cannot open source input file core cmInstr h No such file or directory 这
  • javascript脚本何时被执行

    javascript脚本何时被执行 javascript脚本可以嵌入在内的任意地方 但它何时被调用呢 当浏览器打开HTML文件后 会直接运行不是声明函数的脚本或通过事件调用脚本函数 下面分析这几种情况 1 浏览器在打开页面时执行脚本 当浏览
  • 漫谈软件测试工程师与mercury认证

    漫谈软件测试工程师与mercury认证 出自无忧网 作者 叶赫华 sinckyzhang hotmail com 自从本人从事软件测试培训以来 接触了太多的软件测试工程师 发觉从业者多数存在以下现象 刚刚毕业 踏入IT行业 不懂开发或开发经
  • git分离出分支

    git将历史提交的某个commit作为终点分离出一个新的分支 最近遇到了一个问题 需要从历史提交中的某次commit分离出一个新的分支 使用下面的命令 git checkout b 新分支名 某次commitId 例如 git checko
  • Vue3状态管理库Pinia——核心概念(Store、State、Getter、Action)

    个人简介 个人主页 前端杂货铺 学习方向 主攻前端方向 正逐渐往全干发展 个人状态 研发工程师 现效力于中国工业软件事业 人生格言 积跬步至千里 积小流成江海 推荐学习 前端面试宝典 Vue2 Vue3 Vue2 3项目实战 Node js
  • Filter

    Filter 过滤器 Filter 它是JavaWeb三大组件之一 另外两个是Servlet和Listener 它是在2000年发布的Servlet2 3规范中加入的一个接口 是Servlet规范中非常实用的技术 Filter是一个接口 如
  • Coding Block维护客户化字段

    转载自 http blog sina com cn s blog 4298a2c80102xhco html SAP系统是个各个模块高度集成 无缝衔接的系统 特别是财务模块与各个业务模块的集成程度 是比较高的 因此 财务核算时 会涉及的大量
  • Java 中的自动装箱和拆箱详解

    目录 1 Java 中的自动装箱 2 Java 中的自动拆箱 3 自动装箱和拆箱总结 4 在Java中怎样避免自动装箱和拆箱 1 Java 中的自动装箱 自动装箱是 Java 编译器在基本类型和它们对应的包装类之间进行的自动转换 例如 将