(自动)装箱and(自动)拆箱

news/2024/4/15 8:39:02

目录

【1】前言

【2】实现原理

【3】自动装箱和拆箱的时机

【4】自动装拆箱带来的问题


【1】前言

     在说到拆箱和装箱之前,需要了解Java中有八种基本的数据类型,分别是:byte、short、char、int、long、float、double和boolean。这八种基本类型在Java中都有对应的包装类型:Byte、Short、Character、Integer、Long、Float、Double以及Boolean 。

      有了基本类型为什么还需要包装类型呢?这是由Java本身的语言特性决定的,Java是一种面向对象的编程语言,在学习Java之初就被明确灌输了一个概念:OOP,即面向对象编程。一切皆对象。但是基本类型是不具备Java中对象的某些特征,对象内部可以封装一系列属性和行为,但是这些在基本数据类型中都无法满足,所以对应的包装类型就应运而生了。

       这里的装箱和拆箱的概念描述的其实就是Java中这八种基本数据类型和对应的包装类型之间的转换过程。我们把基本数据类型转换成对应的包装类型的过程叫做装箱。反之就是拆箱。在Java中的装箱和拆箱不是人为操作的,是程序在编译的时候编译器帮助我们完成这项任务的,因此说它是自动的。

【2】为什么需要自动拆/装箱呢?

1)方便

       首先就是方便程序员的编码,我们在编码过程中,可以不需要考虑包装类和基本类型之间的转换操作,这一步由编译器自动替我们完成,开发人员可以有更多的精力集中与具体的业务逻辑。否则的话,一个简单的数字赋值给包装类就得写两句代码,即:首先生成包装类型对象,然后将对象转换成基本数据类型。而这种操作是代码中使用频率很高的操作,导致代码书写量增多。

2)节约空间

       我们在查阅对应包装类的源代码时可以看到,大部分包装类型的valueOf方法都会有缓存的操作,即:将某段范围内的数据缓存起来,创建时如果在这段范围内,直接返回已经缓存的这些对象,这样保证在一定范围内的数据可以直接复用,而不必要重新生成

       这么设计的目的因为:小数字的使用频率很高,将小数字缓存起来,让其仅有一个对象,可以起到节约存储空间的作用。这里其实采用的是一种叫做享元模式的设计模式。可以去具体了解以下这种设计模式,这里就不再过多赘述。

【2】实现原理

1)装箱

        可以看到对于数值类型直接赋值给包装类型,有一个自动装箱的操作,而自动装箱的操作就是利用了Integer中的valueOf方法,这就是前面在节约空间那部分提到的valueOf方法。Integer的valueOf方法中具有缓存的功能,也就是说在数值为-128到127之间的数据,都是被构造成同一个对象,这就是上面提到的享元模式的设计思路:

      注意:尽量不要使用【3】这种方式创建对象,这个构造方法被标记为Deprecated,也就是过时了 。利用构造器构造出来的对象不会经过取缓存操作,所以对于new Integer(1)的操作,得到的Integer对象与e或f进行==比较时,得到的会是false。它的注释中建议使用【4】valueOf进行构建对象。

      其实其他七种包装类型的valueOf方法大多都是这个享元设计模式的逻辑,但是有两个除外:Float和Double。这个其实也很好理解:因为Integer这种类型的数据,-128到127之间的数据是有限个,总共就256个数字,但是对于Float和Double这种类型,它们之间的数据个数就无法计算了,所以它两个就没有采用这种缓存的方式。下面是其他包装类型中的valueOf方法的源码:

 

       通过上面的代码截图可以看到,对于Float和Double都是直接使用了构造器直接构造对应包装类型的对象。对于Boolean类型,就是固定的两个TRUE和FALSE两个常量,它们不会出现变化,这也属于一种缓存。

      对于Byte类型,它是直接全部缓存了,这里使用了cache数组,它在Byte类中定义和初始化如下:

        所以cache数组中存储的就是-128到127范围的所有数。在构建时直接定位到具体的数组位置中去,并将该位置上的数值直接返回即可。

       其余数据类型基本逻辑都差不多了,都有一个缓存值范围,如果超过了,就利用构造器直接构造,否则直接返回缓存的对象。

2)拆箱

上面介绍的valueOf方法是装箱操作的时候使用的,还有一个拆箱操作,看下面这个例子:

上面代码反编译之后就得到:

        可以看到第一步进行了自动装箱操作,在第三行中,基本数据类型和包装类型进行运算,需要将包装类型进行拆箱操作,用到了intValue方法。这个方法其实在源码中很简单,就是一句话,返回value。我们知道任何包装类型,内部都有一个基本数据类型的字段用于存储对应基本类型的值,这个字段就是value。

       相应的其他包装类型在进行拆箱的时候,都会调用对应的xxxValue方法,例如:byteValue、shortValue等等方法。其实内部逻辑都是一样,直接返回存储的value值。

【3】自动装箱和拆箱的时机

1)直接赋值 

       这个情况其实在前面介绍自动装箱的操作的时候,举例代码中就是这种情况,将一个字面量直接赋值给对应包装类型会触发自动装箱操作。 

2)函数参数

       

3)集合操作

       在Java的集合中,泛型只能是包装类型,但是我们在存储数据的时候,一般都是直接存储对应的基本类型数据,这里就有一个自动装箱的过程。

4)运算符运算

       上面在拆箱操作的时候利用的就是这个特性,当基本数据类型和对应的包装类型进行算术运算时,包装类型会首先进行自动拆箱,然后再与基本数据类型的数据进行运算。

       说到运算符,这里对于自动拆箱有一个需要注意的地方:

       这种情况编译是可以通过的,但是在运行的时候会抛出空指针异常,这就是自动拆箱导致的这种错误。因为自动拆箱会调用intValue方法,但是此时a是null,所以会抛异常。平时在使用的时候,注意非空判断即可。

【4】自动装拆箱带来的问题

 1)==比较

        首先就是前面提到的关于==操作符的结果问题,因为自动装箱的机制,我们不能依赖于==操作符,它在一定范围内数值相同为true,但是在更多的空间中,数值相同的包装类型对象比较的结果为false。如果需要比较,可以考虑使用equals比较或者将其转换成对应的基本类型再进行比较可以保证结果的一致性。

2)空指针异常

        这是上面在说到运算符的时候提到的一种情况,因为有自动拆箱的机制,如果初始的包装类型对象为null,那么在自动拆箱的时候的就会报NullPointerException,在使用时需要格外注意,在使用之前进行非空判定,保证程序的正常运行。

3)内存浪费

这里有个例子:

面代码中的 sum+=i 这个操作其实就是拆箱再装箱的过程,拆箱过程是发生在相加的时候,sum本身是Integer,自动拆箱成int与 i 相加。将得到的结果赋值给sum的时候,又会进行自动装箱,所以上面的for循环体中一句话,在编译后会变为:

       每次调用valueOf方法都会返回一个Integer对象,所以在进行了5000次循环后,会出现大量的无用对象造成内容空间的浪费,同时加重了垃圾回收的工作量,所以在日常编码过程中需要格外注意,避免出现这种浪费现象。

4)方法重载问题

       每次调用valueOf方法都会返回一个Integer对象,所以在进行了5000次循环后,会出现大量的无用对象造成内容空间的浪费,同时加重了垃圾回收的工作量,所以在日常编码过程中需要格外注意,避免出现这种浪费现象。

      所以可以发现,当出现这种情况的时候,是不会发生自动装箱和拆箱操作的。可以正常区分。

有人身居高堂久睡不醒,有人身居陋巷仍以萤火为光。

前路昭然,你我仍需奋进!

铁铁们加油!!!


http://www.ppmy.cn/news/534194.html

相关文章

关于元胞自动机

元胞自动机(cellular automata,CA) 是一种时间、空间、状态都离散,空间相互作用和时间因果关系为局部的网格动力学模型,具有模拟复杂系统时空演化过程的能力。 其实在去年暑假准备国赛的时候试图过自学,但受限于,网上…

自动拆箱与自动装箱

为什么需要包装类 Java 中为了提高效率,提供了八种基本数据类型,为什么还要提供包装类呢? 这个问题,其实前面已经有了答案,因为 Java 是一种面向对象语言,很多地方都需要使用对象而不是基本数据类型。比如…

练腹肌

1:练腹肌最好的办法还是仰卧起坐,每次做100-200个,20-30个为1组,最少要做5组,具体的要看个人情况。可以适当增加点重量,手拿个哑铃或铁饼什么的,放在脑后,效果更好。 2:…

韩金氏秀腹宝

韩金氏秀腹宝:www.hxdj.net秀腹宝首要成分: 韩国金氏集团和韩国首尔大学女子生殖医学研讨中间在关于产后妊娠纹疑问通过多次配方调整实验,结尾判定以PAL-GQPR胶原蛋白、橄榄油、芸香苷、水溶性辣椒精华、雪莲、薰衣草、VE、VB6、VC等组方又配…

自动装箱和自动拆箱

在java中一共有8种基本类型,并且在jdk1.4的时候添加了对应的八个包装类型如下表所示: 基本类型与包装类型对照表 intIntegershortShortlongLongdoubleDoublefloatFloatcharCharacterbyteBytebooleanBoolean 都知道,java中的类型可以分为两类…

什么是元胞自动机

看了网上的资料和大神Stephen Wolfram的论文,对元胞自动机有了一点基本的了解。 先贴一段维基百科的解释: 细胞自动机(英语:Cellular automaton),又称格状自动机、元胞自动机,是一种离散模型&a…

咕咕机vs喵喵机测评

咕咕机vs喵喵机测评 本次对比测评的机子,来自之前妹妹入手的喵喵机和我刚刚入手的咕咕机。 之前妹妹有买过喵喵机,觉得很方便想推荐给我,碰巧咕咕机推出了新款,价格合算,外表美观,于是干脆入手了咕咕机。顺…

元胞自动机概念与实例

简介:元胞自动机(cellular automata,CA) 是一种时间、空间、状态都离散,空间相互作用和时间因果关系为局部的网格动力学模型,具有模拟复杂系统时空演化过程的能力。 主要内容: 一、元胞 元胞可以是数字,字…

元胞自动机(Cellular automata)

定义 元胞自动机,也叫细胞自动机,是一种离散模型。散布在规则格网 (Lattice Grid)中的每一元胞(Cell)取有限的离散状态,遵循同样的作用规则,依据确定的局部规则作同步更新。大量元胞通过简单的相互作用而构成动态系统的演化。不同…

有助瘦腰收腹的健身动作

减肥操是局部减肥最有效的运动方式,而腰腹部、手臂、腿部是身体最容易发胖的部位。今天,就来为你推荐一套三式减肥操,助你快速收腹、瘦腿、瘦手臂,塑造更完美的局部线条哦! 第一式 准备器材:吊环 针对部位:…

元胞自动机(又称细胞自动机)

元胞自动机(cellular automata): 又称格状自动机、元胞自动机,是一种离散模型,在可计算性理论、数学及理论生物学都有相关研究。它是由无限个有规律、坚硬的方格组成,每格均处于一种有限状态。整个格网可以…

元胞自动机简介

摘要: 元胞自动机能利用简单的局部规则和离散方法描述复杂的全局的连续系统,已成为探索复杂系统的一种有效工具。文章 阐述了元胞自动机的发展历程、结构、特征及基本理论与方珐;介绍了元胞自动机在寡头垄断行为、交通管理及工程运输、城市…

四轴机械臂使用说明

导航目录 一、手机端APP无线控制(一)、上电操作(二)、蓝牙连接(三)、功能说明 二、电脑端软件有线控制(一)、上电操作(二)、串口连接(三&#xff…

跳板机

现在一定规模互联网企业,往往都拥有大量服务器,如何安全并高效的管理这些服务器是每个系统运维或安全运维人员必要工作。现在比较常见的方案是搭建堡垒机环境作为线上服务器的入口,所有服务器只能通过堡垒机进行登陆访问,合格的堡…

滑台四轴机械臂使用说明

导航目录 一、手机端APP无线控制(一)、上电操作(二)、蓝牙连接(三)、功能说明 二、电脑端软件有线控制(一)、上电操作(二)、串口连接(三&#xff…

练腹肌的方法

仰卧起坐当然是腹肌训练的首选。 但是,怎么做才是最有效果的? 如果你是个胖子的话,我是说如果你的腹部脂肪层比较厚。 你必须采取有氧训练式的练习方法。 先慢跑。10分钟。 躺下做仰卧起坐。 然后爬起来立刻做冲刺跑。坚持30秒以上。 …

AutoGPT 英文版安装过程

自从2022年11月chatGPT的发布3.0GPT大模型,在中国掀起一股AI学习热潮,国内百度2023年4月份发布文心一言,把AI推上另一个高潮,最直接的是问答,我输入一句话,AI帮生成一段文字或一个视频,但是国内…

香橙派4 2. 驱动usb2.0芯片cy7c68013

0. 环境 - 香橙派4(Orangepi4_2.1.2_ubuntu_bionic_desktop_linux4.4.179.img) - EZ-USB FX2LP CY7C68013A USB 核心板 1. 下载FX3_SDK_1.3.4_linux EZ-USB™ FX3 Software Development Kit https://www.infineon.com/cms/en/design-support/tools/sdk…

西门子PLC和松下PLC的区别

西门子的编程软件和程序结构 1. 编程软件 西门子公司针对SIMATIC系列PLC提供了很多种的编程软件,主要有STEP MICRO/DOS和STEP MICRO/WIN;STEP mini;标准软件包STEP7 S7系列的PLC的编程语言非常丰富,有LAD、STL、SCL…

Day43 | 1049. 最后一块石头的重量II, 494. 目标和, 474.一和零

Day43 | 1049. 最后一块石头的重量II, 494. 目标和, 474.一和零 最后一块石头的重量II LeetCode题目:https://leetcode.cn/problems/last-stone-weight-ii/ 题目中的背包理解 可以将其中的一个子问题抽象冲背包问题,即题中要求求得最后一块儿石头的最…
最新文章