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 中的自动装箱和拆箱详解 的相关文章

  • strictfp关键字

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

    基本数据类型对象包装类 为了方便操作基本数据类型值 将其封装成了对象 在对象中定义了属性和行为丰富了该数据的操作 用于描述该对象的类就称为基本数据类型包装类 byte Byte short Short int Integer long Lo
  • 【Java】抽象类和接口

    并没有那么多天赋异禀 优秀的人总是努力翻山越岭 目录 1 抽象类 1 1 抽象类的概念 1 2 抽象类的语法 1 3 抽象类的特性 1 4 抽象类的作用 2 接口 2 1 接口的概念 2 2 接口的语法规则 2 3 接口的使用 2 4 接口
  • 文件上传优化

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

    最近公司准备将旧系统的 NET部分翻版 项目除了有后台的还有个与设备对接的客户端用蓝牙连接的 所有这周对相关技术做了一个验证 搜了一下Java 蓝牙相关信息 我去资料也太少了 少也就算了连bluecove库也是有问题的 经过艰难的查找 最终
  • java - 面向对象程序的三大特性 封装、继承、多态

    目录 1 封装 1 1访问限定符 1 2包 1 3导入包中的类 1 4如何自定义包 1 5 包的访问权限控制举例 1 6 常见的包 1 7如果修改封装好的成员变量 2 继承 什么继承 子类中访问父类成员变量 子类和父类不存在同名成员变量 子
  • JAVA基础:线程池的使用

    目录 1 概述 2 线程池的优势 2 1 线程池为什么使用自定义方式 2 2 封装的线程池工具类有什么好处 3 线程池的七大参数 3 线程池的创建 3 1 固定数量的线程池 3 2 带缓存的线程池 3 3 执 定时任务 3 4 定时任务单线
  • 语句执行顺序对判断语句条件的影响

    对比相同的输出结果下 不同的语句执行顺序对判断语句条件的影响 public class Homework1 public static void main String args 输出1 100偶数 每5个一行 一行中的每个数字之间使用逗号
  • 如何优雅的打印数组

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

    目录 一 websocket简介 二 背景 三 优点 1 控制开销 2 实时性更强 3 保持连接状态 4 更好的二进制支持 5 支持扩展和更好的实现压缩效果 四 原理 1 客户端 服务器建立TCP连接 三次握手 2 TCP连接成功后 客户端
  • JqGrid完整例子

    之前写过一篇过于ajax异步加载jqgrid的文章 那个只是一个特殊的情况 如果创建不同数据库表的jqgrid 必须分别写servlet dao层和连接池 很麻烦 今天我写了一个万能的写法 客官只要在前台js中写入表格名称和字段名称即可实现
  • Java的运算符

    目录 一 什么是运算符 二 算术运算符 1 基本四则运算符 加减乘除模 2 增量运算符 3 自增 自减运算符 三 关系运算符 四 逻辑运算符 重点 1 逻辑与 2 逻辑或 3 逻辑非 4 短路求值 五 位运算符 1 按位与 2 按位或 3
  • java 16进制与图片互转

    十六进制转成图片 十六进制转成图片 author Administrator public static void saveToImgFile String src String output if src null src length
  • UDP网络基础知识简介

    作者简介 CSDN2021博客之星亚军 新星计划导师 博客专家 哪吒多年工作总结 Java学习路线总结 搬砖工逆袭Java架构师 关注公众号 哪吒编程 回复1024 获取Java学习路线思维导图 大厂面试真题 加入万粉计划交流群 一起学习进
  • java基础之内存机制详解

    今天有看到一篇好的关于java内存机制的文章 果断转载过来 哈哈哈哈哈哈 堆区 1 存储的全部是对象 每个对象都包含一个与之对应的class的信息 class的目的是得到操作指令 2 jvm只有一个堆区 heap 被所有线程共享 堆中不存放
  • 【Java】运算符

    我不去想是否能够成功 既然选择了远方 便只顾风雨兼程 汪国真 目录 1 认识运算符 1 1 认识运算符 1 2 运算符的分类 2 算术运算符 2 1 四则运算符 2 2 复合赋值运算符 2 3 自增 自减 运算符 3 关系运算符 4 逻辑运
  • 缓冲流【Buffered】

    缓冲流 Buffered 缓冲流我们理解为原来的使用数组方式进行数据传输的一种增强 按照类型分为 字符缓冲流 BufferedReader BufferedWriter 字节缓冲流 BufferedInputStream BufferedO
  • java必懂之"=="与equals的区别

    屁话不多说 直接上代码 equals和关系运算符 的区别 author 刘威辰的秘密花园 1 用在基本数据类型boolean a b 2 判断引用是否指向同一个地址且内容是否相同 equals 1 用于判断两个变量是否对同一个对象的引用 即
  • Java 简单修饰符补充学习笔记(基础)

    前言 顾名思义 这里是补充修饰符的学习笔记 通配符 顾名思义即可 const 常变量修饰符 首先const是constant 恒定不变的 的缩写 const 就是描述变量为常量的修饰符 关键字 或者说 const 是定义常变量的关键字 用
  • 【JAVA日志框架】JUL,JDK原生日志框架详解。

    前言 Java日志体系混乱 Java日志框架系列 清晰简洁整理好整个Java的日志框架体系 第一篇 JDK原生日志框架 JUL 目录 1 概述 2 日志级别 3 配置 4 继承关系 1 概述 日志框架的核心问题 日志是用来记录应用的一些运行

随机推荐

  • 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 编译器在基本类型和它们对应的包装类之间进行的自动转换 例如 将