包装类 ---- java

news2024/9/22 10:08:22

  思维导图:

 

  在 Java 中,自动装箱(autoboxing)和拆箱(unboxing)是一种自动将基本数据类型和对应的包装类进行转换的机制。

  一:基本数据类型和对应的包装类

 

   二:装箱和拆箱 

int i = 10;

// 装箱操作,新建一个 Integer 类型对象,将 i 的值放入对象的某个属性中
Integer ii = Integer.valueOf(i);
Integer ij = new Integer(i);

// 拆箱操作,将 Integer 对象中的值取出,放到一个基本数据类型中
int j = ii.intValue();

   2.1自动装箱和自动拆箱 

  通过上述代码可以看到在使用过程中,装箱和拆箱带来不少的代码量,为了减少开发者的负担,java 提供了自动机制。

int i = 10;
Integer ii = i; // 自动装箱
Integer ij = (Integer)i; // 自动装箱
int j = ii; // 自动拆箱
int k = (int)ii; // 自动拆箱

   2.2自动装箱和自动拆箱的原理

  1. 自动装箱:

  • 当把一个基本数据类型的值赋给对应的包装类对象时,会自动进行装箱操作。例如,将int类型的值赋给Integer对象,Integer i = 10;,在这个过程中,Java 会自动创建一个Integer对象,并将基本数据类型int的值10包装到这个对象中。

  •原理: 实际上,Java 编译器会在后台调用Integer.valueOf(int)方法来完成装箱操作。对于在一定范围内的值(通常是 -128 到 127),Java 会使用缓存的对象,以提高性能。

  2. 自动拆箱:

  • 当从包装类对象中获取基本数据类型的值时,会自动进行拆箱操作。例如,从Integer对象中获取int类型的值,int n = i;,这里i是一个Integer对象,Java 会自动将Integer对象中的值拆箱为基本数据类型int并赋给变量n。

• 原理:编译器会在后台调用包装类的xxxValue()方法来实现拆箱,对于Integer类,会调用intValue()方法。

  原理图:

 

  易错点:看如下代码 

public static void main(String[] args) {
Integer a = 127;
Integer b = 127;
Integer c = 128;
Integer d = 128;
System.out.println(a == b); //true
System.out.println(c == d); //false 为什么????
}

   在 Java 中,Integer对于值在 -128 到 127 之间会进行缓存,主要有以下原因:

  一、提高性能

  1. 频繁使用小范围整数:在很多程序中,小范围的整数(如 -128 到 127)被频繁使用。通过缓存这些值,可以避免频繁地创建新的Integer对象,减少内存分配和垃圾回收的开销,从而提高程序的性能。

  2. 减少对象创建:当需要一个在这个范围内的Integer对象时,可以直接从缓存中获取,而不是通过调用构造函数创建新的对象。这样可以快速返回已经存在的对象,节省时间和资源。

  二、优化内存使用

  1. 重复利用对象:缓存机制使得相同的值在内存中只存在一个Integer对象,避免了多个相同值的对象占用额外的内存空间。特别是在处理大量小范围整数的场景下,可以显著减少内存的使用。

  2. 空间效率:对于小范围的整数,通过缓存可以有效地管理内存,避免不必要的对象创建和内存浪费。

  三、常见场景适用性

  1. 一般业务逻辑:在很多常规的业务逻辑中,小范围的整数经常出现,例如循环计数器、数组索引等。缓存机制可以很好地适应这些常见的场景,提高程序的运行效率。

  2. 与数据库交互:在与数据库交互时,一些数据库返回的整数字段值可能在小范围内。缓存机制可以在处理这些返回值时提高性能,减少对象创建和内存占用。

  在 Java 中,除了Integer类,以下几个类也进行了类似的缓存优化:

一、Byte 类

缓存了-128到127之间的Byte对象。这是因为在实际应用中,小范围的字节值经常被使用,缓存可以提高性能并减少内存占用。

二、Short 类

同样缓存了-128到127之间的Short对象。对于小范围的短整型值,这种缓存机制可以避免不必要的对象创建。

三、Long 类

缓存了-128到127之间的Long对象。与其他整数类型类似,在处理小范围的长整型值时,缓存可以提高效率。

四、Character 类

缓存了0到127之间的Character对象,这个范围涵盖了 ASCII 字符集。因为 ASCII 字符在很多程序中被频繁使用,缓存这些字符对象可以提高性能。

 

  三:应用场景

  3.1集合框架的使用

  • 在 Java 的集合框架中,如List、Set、Map等,只能存储对象类型,不能直接存储基本数据类型。这时自动装箱和拆箱就非常有用。

  • 请看如下代码:

List<Integer> list = new ArrayList<>();

 list.add(5);

  说明:这里先将基本数据类型5自动装箱为Integer对象,然后添加到List中。当从集合中取出元素时,又会自动拆箱为基本数据类型。

  • 在使用Map时也类似:

Map<String, Integer> map = new HashMap<>(); 
map.put("key", 10);

  说明:这里将基本数据类型10装箱为Integer对象作为值存入Map中。

  3.2方法参数和返回值

  • 当一个方法的参数是包装类类型,而传入的是基本数据类型时,会自动进行装箱操作。同样,当方法的返回值是包装类类型,而实际返回的是基本数据类型时,会自动进行拆箱操作。

   如下代码:

public Integer add(Integer a, Integer b) { 
return a + b; 
};

int result = add(3, 5);//调用add方法,接收返回值

  说明:调用int result = add(3, 5);,这里3和5会自动装箱为Integer对象传入方法,方法返回的Integer对象又会自动拆箱为int类型赋给result变量。

  3.3 泛型的使用

  • 在泛型中,只能使用对象类型,不能使用基本数据类型。自动装箱和拆箱使得可以在泛型中使用基本数据类型的包装类,从而提供了更大的灵活性。

  • 例如:

List<Integer> list = new ArrayList<>();

  这里使用了泛型Integer,可以存储包装后的基本数据类型。

  3.4条件判断和循环

  • 在条件判断和循环中,经常会涉及到基本数据类型和包装类的转换。

  • 例如:for (Integer i = 0;i < 10;i++) {... },这里的循环变量i是Integer类型,在每次循环中,会自动拆箱为基本数据类型进行比较和自增操作。

  总结:自动装箱和拆箱机制使得 Java 代码在处理基本数据类型和包装类之间的转换更加简洁和方便,提高了代码的可读性和可维护性。

  四:自动装箱和拆箱的缺陷:

  4.1性能开销

  4.1.1 频繁的自动装箱和拆箱操作可能会带来性能问题,尤其是在性能敏感的代码段中。每次装箱和拆箱都涉及到方法调用,对于大量的操作来说,这些方法调用的累积开销可能会变得显著。

  4.1.2 创建对象的开销:自动装箱可能会创建新的对象,如果这些对象没有被及时回收,会占用内存空间,增加垃圾回收的压力。

  4.2可能导致的错误

  4.2.1 空指针异常:由于包装类可以为null,而基本数据类型不能为null。在自动拆箱时,如果一个包装类对象为null,进行自动拆箱操作就会导致空指针异常。

Integer num = null;
int n = num; // 此处会抛出空指针异常


  4.2.2 不易察觉的错误:自动装箱和拆箱可能会掩盖一些类型转换的问题,使得错误难以在代码审查时被发现。例如,在一个复杂的表达式中,自动装箱和拆箱可能会导致意外的结果,但开发人员可能不容易察觉问题的根源。

  4.3可读性的影响(在某些复杂情况下)

  在一些非常复杂的代码中,自动装箱和拆箱可能会使代码的可读性降低。因为自动进行的类型转换可能会让读者难以确定实际发生的操作,需要仔细分析才能理解代码的意图。

  五:如何避免自动装箱和拆箱的缺陷:

  5.1性能开销方面

   注意代码优化:

  • 在性能关键的代码区域,尽量避免频繁的自动装箱和拆箱操作。例如,在大量循环或频繁调用的方法中,直接使用基本数据类型而不是依赖自动装箱。

  • 对于集合操作,如果确定集合中存储的是基本数据类型的值,可以考虑使用基本数据类型的数组或者专门为基本数据类型设计的集合类,如java.util.IntSummaryStatistics等,避免自动装箱后放入普通集合中带来的性能开销。

   合理使用缓存:

    • 对于像Integer等包装类,了解其缓存机制的范围(通常是 -128 到 127)。如果在这个范围内操作,可以利用缓存减少对象创建。如果操作的值超出这个范围,要意识到可能会创建新的对象,谨慎评估性能影响。

  5.2 可能导致的错误方面

  空指针检查:

  • 在进行自动拆箱之前,务必进行空指针检查,以避免空指针异常。可以使用条件判断语句来确保包装类对象不为null再进行拆箱操作。
 

Integer num = null;
if (num!= null) {
    int n = num;
}


  明确类型转换:

  • 在代码中,对于可能涉及自动装箱和拆箱的地方,尽量明确地进行类型转换,以便更好地理解代码的行为和潜在风险。例如,使用intValue()方法进行显式的拆箱操作,而不是依赖自动拆箱。


Integer numObj = new Integer(10);
int num = numObj.intValue();


    5.3可读性影响方面

   清晰的代码结构:

    • 在复杂的代码中,尽量使用清晰的变量命名和代码结构,以便更好地理解自动装箱和拆箱的发生位置和目的。避免在复杂表达式中过度依赖自动装箱和拆箱,以免使代码难以理解。

    • 可以添加适当的注释来解释自动装箱和拆箱的目的和潜在风险,提高代码的可读性和可维护性。

   单元测试:

    • 编写全面的单元测试,覆盖可能涉及自动装箱和拆箱的代码路径。通过单元测试可以更容易地发现由于自动装箱和拆箱导致的错误,确保代码的正确性。

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

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

相关文章

Spring Boot 3.3新特性解析:CDS支持与Base64配置

前言 Spring Boot 3.3.0 已经发布&#xff0c;其中包含对 CDS支持与Base64配置。 CDS&#xff08;Class Data Sharing&#xff09;是一项JVM功能&#xff0c;允许在多个JVM实例之间共享类元数据&#xff0c;从而减少应用程序的启动时间和内存占用。Spring Boot 3.3提供了对CD…

Web前端全栈Vue3项目实战:‌从零到一的完整指南

Web前端全栈Vue3项目实战&#xff1a;‌从零到一的完整指南 在当今的前端开发领域&#xff0c;‌Vue.js 凭借其简洁、‌易学且高效的特点&#xff0c;‌成为了众多开发者的首选框架。‌随着 Vue 3 的发布&#xff0c;‌其在性能、‌类型支持以及组合式 API 等方面的提升&#…

Influxdb简介

InfluxDB 是一个开源的、专门为处理时序数据&#xff08;Time Series Data&#xff09;设计的数据库管理系统。它由 InfluxData 开发&#xff0c;旨在高效地存储和查询大量的时序数据&#xff0c;如监控数据、传感器数据、日志、指标和事件等。

图论(1)

一、无序对的定义 无序对中的两元素不分先后 无序积是无序对的集合 无序对里面的元素交换位置还是之前的无序对 二、图 三、图的表示 1、图的表示法 有集合表示法、画图表示法、矩阵表示法 集合表示法&#xff1a;把所有边写在一个集合里&#xff0c;所有点写在一个集合里…

C语言:常用技巧汇总

一、字符串存储在数组中 int main() {char* arr[7] {"xiaoming","zhangsan","李四"};printf("%s\n", arr[0]);printf("%s\n", arr[2]);return 0; } 二、scanf()函数用法 2.1 scanf()输入字符串 int main() {char arr[10…

沸点 | LDBC 第18届 TUC 会议召开,专家孙宇熙受邀参加并发表演讲

图数据管理领域国际权威组织LDBC&#xff08;Linked Data Benchmark Council&#xff09;于8月30日至31日在广州举办了第18届LDBC TUC会议。作为图数据库领域的创新引领者&#xff0c;嬴图受邀参加此次盛会&#xff0c;国际高性能计算与存储系统专家、大数据专家、图专家及嬴图…

国赛数模C题模型(五)

熵权法 原理介绍 熵权法&#xff1a;&#xff08;1&#xff09;熵&#xff1a;指标的信息熵。信息熵描述所有可能发生事件的不确定性。 ​ &#xff08;2&#xff09;权&#xff1a;指标的权重&#xff0c;描述指标的重要程度。 ​ &#xff08;3&#xff09;熵权法&#xff1…

Java实现加密(六)国密SM2算法

目录 一、SM2 简介1.1 概述1.2 国密与国际密的对应关系1.3 优势1.4 ECC加密算法 vs RSA加密算法二、SM2 应用场景2.1 数据加密2.2 密钥协商2.3 数字签名三、Java 实现 SM2 的两种方式3.1 Maven 依赖3.2 实现方式一1)SM2Utils.java2)SignatureSM2Util.java3)Param.java4)测试…

界面控件DevExpress中文教程:如何使用AI扩展Excel计算?

DevExpress WinForms拥有180组件和UI库&#xff0c;能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForms能完美构建流畅、美观且易于使用的应用程序&#xff0c;无论是Office风格的界面&#xff0c;还是分析处理大批量的业务数据&#xff0c;它都能轻松胜…

人工智能 | Mistral 大语言模型

Mistral AI Mistral AI team Mistral AI 是一家销售人工智能产品的法国公司。它由 Meta Platforms 和 Google DeepMind 的前员工于 2023 年 4 月创立。该公司于 2023 年 10 月筹集了 3.85 亿欧元&#xff0c;2023 年 12 月估值超过 20 亿美元 Mistral.AI 愿景与使命 我们是一…

Linux动态链接库

一、背景 我们使用Linux的过程中&#xff0c;例如安装程序或者部署一些如Python等&#xff0c;可能会遇到过如下动态链接库(共享库)报错: ImportError: libcrypto.so.10: cannot open shared object file: No such file or directory $"./lib/python3.8/lib/python3.8/ss…

同三维TM6-6 有线6级联会议麦克风详情介绍

同三维TM6-6 有线6级联会议麦克风 信息通讯类智能阵列麦克风 有线传输&#xff0c;强抗干扰、可级联、长续航、低延时 6个麦克风级联&#xff0c;通过3.5音频线级联, 可以同时使用3.5mm LINE IN/OUT、USB有线连接PC端&#xff0c;每条音频线是3米&#xff0c;可应用在视频会…

使用vscode编辑matlab完美解决方法

vscode里面的matlab插件都不好用&#xff0c;需要搭配互补一下 1先安装MATLAB 这个插件可以进行代码高亮、格式化、跳转&#xff0c;F5运行所有代码&#xff0c;或者选中要运行的代码&#xff0c;右键单独运行&#xff0c; 优点&#xff1a;运行速度很快&#xff0c;和matlab里…

idea新建父工程和添加导入新模块的步骤

如何在idea中新建一个父工程&#xff0c;然后在父工程下新建多个微服务模块&#xff1f; 一、新建父工程 1.1 新建New Project 1.2 删掉多余文件 创建好后&#xff0c;把多余的文件删掉&#xff0c;变成这样 1.3 修改pom文件 添加<packaging>pom</packaging>…

【Webpack】基本使用方法

参考视频&#xff1a; 30 分钟掌握 Webpack_哔哩哔哩_bilibili 什么是webpack 简单来说就是一个 打包工具&#xff0c; 可以将互相依赖的html、css、js以及图片字体等资源文件&#xff0c;经过处理打包成一个可执行的项目文件 &#x1f330;看例子 环境初始化 在需要使用…

ai智能写作助手批量生成文章,提升工作效率!

在当今快节奏的工作环境中&#xff0c;时间就是金钱&#xff0c;效率就是生命。对于需要大量产出文章的工作者来说&#xff0c;如何在有限的时间内创作出高质量的内容&#xff0c;成为了一个亟待解决的问题。而AI智能写作助手的出现&#xff0c;为这一问题提供了解决方案。本文…

godot开发初体验

点击加号可以创建一个新的场景 点击其它节点可以添加节点 想对某个节点添加子节点可以右键这个节点,然后点击添加子节点 在左下角的文件系统中,可以右键某个场景,并将其设置为主场景,主场景作为程序的入口 点击项目->项目设置-> 输入映射,可以添加一个新的动作,在添加新动…

游戏应用|空地模型实景融合,还原《黑神话:悟空》游戏场景

古色斑驳&#xff0c;巍峨险峻&#xff0c;是历史的低语&#xff0c;诉说着千百年的沧桑与辉煌&#xff1b;飞檐翘角&#xff0c;雕梁画栋&#xff0c;凝聚着时代的文明与智慧。在数字化浪潮下&#xff0c;我们利用实景三维技术&#xff0c;翻开了中华古建筑这本伟大的史诗。 P…

快速入门Go:Go + gin + MongoDB

Go 进阶:Go + gin + MongDB 极速搭建EcommerceSys电商系统 前言 本章节适合有一定基础的 Golang 初学者,通过简单的项目实践来加深对 Golang 的基本语法和 Web 开发的理解。 本文章持续更新中,请关注… 项目结构 项目流程图 技术栈(待补充)项目结构项目路由 (待补充) …

合宙LuatOS开发板Core_Air780EP使用说明

Core-Air780EP 开发板是合宙通信推出的基于 Air780EP 模组所开发的&#xff0c; 包含电源&#xff0c;SIM卡&#xff0c;USB&#xff0c;天线&#xff0c;音频等必要功能的最小硬件系统。 以方便用户在设计前期对 Air780EP模块进行性能评估&#xff0c;功能调试&#xff0c;软…