揭秘装箱与拆箱操作
- 格式:doc
- 大小:154.00 KB
- 文档页数:31
变量是存放特定数据类型值的容器!由于C#中所有的数据类型都是由基类System.Object继承而来的,所以值类型和引用类型的值可以通过显式(或隐式)操作相互转换,而这转换过程也就是装箱(boxing)和拆箱(unboxing)过程。
1.值类型。
1.值类型是在栈中分配内存。
值类型的数据值存储在内存的堆栈中,从内存的堆栈中可以快速的访问这些数据值。
声明没有初始化,不使用,编译不会报错;在声明时没有初始化,使用,编译会报错。
2.值类型超出作用范围系统自动释放内存。
垃圾回收机制不参与回收。
3.将一个值类型变量的内容赋值给另一个值类型的变量时,变量值被拷贝。
4.主要由两类组成:结构,枚举(enum),结构分为以下几类:1.整型(Sbyte、Byte、Char、Short、Ushort、Int、Uint、Long、Ulong)2.浮点型(Float、Double)3.decimal4.bool5.用户定义的结构(struct)2.引用类型。
1.引用类型在堆中分配内存,初始化时默认为null。
在栈中保存指向堆中分配内存的地址。
操作时通过栈中的指针寻找。
2.引用类型是通过垃圾回收机制进行回收。
3.包括类、接口、委托、数组以及内置引用类型object与string。
4.将一个引用类型变量的内容赋值给另一个引用类型的变量时,只是变量的内存地址被拷贝。
装箱:将值类型转换为引用类型。
拆箱:将引用类型转换为值类型。
1.装箱是值类型到 object 类型或到此值类型所实现的任何接口类型的隐式转换。
对值类型装箱会在堆中分配一个对象实例,并将该值复制到新的对象中。
拆箱(取消装箱)是从 object 类型到值类型或从接口类型到实现该接口的值类型的显式转换。
取消装箱(拆箱)操作包括:0.检查对象实例,确保它是给定值类型的一个装箱值。
(拆箱后没有转成原类型,编译时不会出错,但运行会出错,所以一定要确保这一点。
用GetType().ToString()判断时一定要使用类型全称,如:System.String 而不要用String。
解析C#中的装箱与拆箱的详解1. 装箱在值类型向引⽤类型转换时发⽣2. 拆箱在引⽤类型向值类型转换时发⽣光上述两句话不难理解,但是往深处了解,就需要⼀些篇幅来解释了。
我们先看装箱时都会发⽣什么事情,下⾯是⼀⾏最简单的装箱代码复制代码代码如下:object obj = 1;这⾏语句将整型常量1赋给object类型的变量obj;众所周知常量1是值类型,值类型是要放在栈上的,⽽object是引⽤类型,它需要放在堆上;要把值类型放在堆上就需要执⾏⼀次装箱操作。
这⾏语句的IL代码如下,请注意注释部分说明:复制代码代码如下:.locals init ([0] object objValue) //以上三⾏IL表⽰声明object类型的名称为objValue的局部变量IL_0000: nopIL_0001: ldc.i4.s 9 //表⽰将整型数9放到栈顶IL_0003: box [mscorlib]System.Int32 //执⾏IL box指令,在内存堆中申请System.Int32类型需要的堆空间IL_0008: stloc.0 //弹出堆栈上的变量,将它存储到索引为0的局部变量中以上就是装箱所要执⾏的操作了,执⾏装箱操作时不可避免的要在堆上申请内存空间,并将堆栈上的值类型数据复制到申请的堆内存空间上,这肯定是要消耗内存和cpu资源的。
我们再看下拆箱操作是怎么回事:请看下⾯的C#代码:复制代码代码如下:object objValue = 4;int value = (int)objValue;上⾯的两⾏代码会执⾏⼀次装箱操作将整形数字常量4装箱成引⽤类型object变量objValue;然后⼜执⾏⼀次拆箱操作,将存储到堆上的引⽤变量objValue存储到局部整形值类型变量value中。
同样我们需要看下IL代码:复制代码代码如下:.locals init ([0] object objValue,[1] int32 'value') //上⾯IL声明两个局部变量object类型的objValue和int32类型的value变量IL_0000: nopIL_0001: ldc.i4.4 //将整型数字4压⼊栈IL_0002: box [mscorlib]System.Int32 //执⾏IL box指令,在内存堆中申请System.Int32类型需要的堆空间IL_0007: stloc.0 //弹出堆栈上的变量,将它存储到索引为0的局部变量中IL_0008: ldloc.0//将索引为0的局部变量(即objValue变量)压⼊栈IL_0009: unbox.any [mscorlib]System.Int32 //执⾏IL 拆箱指令unbox.any 将引⽤类型object转换成System.Int32类型IL_000e: stloc.1 //将栈上的数据存储到索引为1的局部变量即value拆箱操作的执⾏过程和装箱操作过程正好相反,是将存储在堆上的引⽤类型值转换为值类型并给值类型变量。
任务二装、拆箱业务操作任务引导港星货运代理公司仓库接到货主交货,共300包鱼粉,如图4-3-3所示,要求作为理货人员将其装入箱号为CBHU1111119的集装箱内,并保证货物和集装箱设备的安全。
图4-3-3 仓库中等待装箱的袋装鱼粉学习目标知识目标:1.了解集装箱货物的种类2.熟悉现场装箱作业的类型能力目标:学会车辆类货物如何装箱任务要求集装箱货物包括各种形式,如桶装货(又分木桶、铁桶、纸板桶等)、箱装货(又分纸箱货、木箱货等)、货板货、捆包货等,还有汽车等裸装货。
这些货物的装箱方式各有不同要求,我们需要逐一进行了解。
本次任务中的鱼粉属于袋装货,要注意使用种类适合的集装箱,根据货物总重计算出需要的箱量,并在装箱过程中注意是否需要捆扎、加固、垫箱等操作。
知识储备一般情况下,装、拆箱业务都是在集装箱后方堆场或集装箱货运站(Container Freightstation ,简称CFS)进行的。
根据货物种类不同,所用包装不同,装拆箱作业时有不同的作业方法和作业要求。
下面对集装箱装拆箱作业进行介绍:一、装箱作业与注意事项集装箱堆场各类货物的装箱操作:1.纸箱货的装箱操作(1)纸箱装箱操作的注意事项。
纸箱是集装箱货物中最常见的一种包装,一般用于包装比较精细的和质轻的货物。
①如集装箱内装的是统一尺寸的大型纸箱,空隙会产生。
当空隙为10cm左右时,一般不需要对货物进行固定。
但当空隙很大时,就需要按货物具体情况加以固定。
②如果不同尺寸的纸箱混装,应就纸箱大小进行合理搭配,做到紧密堆装。
③拼箱的纸箱货应进行隔票。
隔票时可使用纸、网、胶合板、电货板等材料,也可以用粉笔、带子等做记号。
④纸箱货不足以装满一个集装箱时,应注意纸箱的堆垛高度,以满足使集装箱底面占满的要求。
(2)纸箱的装载和固定操作①装箱是要从箱里往外装,或从两侧往中间装。
②在横向产生250〜300cm的空隙时,可以利用上层货物的重量把下层货物压住,最上层货物一定要塞满或加以固定。
自动装箱和自动拆箱原理今天咱们来唠唠编程世界里一个挺有趣的话题——自动装箱和自动拆箱。
这俩概念听起来是不是有点神秘兮兮的?别担心,让我用大白话给您讲明白。
咱们先来说说自动装箱。
想象一下,您正在编程,就好像在搭建一个神奇的数字城堡。
有时候您想把一个基本数据类型,比如说一个小小的整数 5 ,当成一个对象来处理。
这时候,自动装箱就像一个神奇的魔法,它能把这个简单的整数 5 瞬间变成一个 Integer 对象。
是不是很神奇?就好像给这个数字穿上了一件华丽的外衣,让它从一个“小透明”变成了一个有身份有地位的“贵族”。
那这个魔法是怎么实现的呢?其实呀,在幕后有一套聪明的机制在运作。
当您写下类似 `Integer num = 5;` 这样的代码时,编译器就会悄悄地施展魔法,帮您把这个基本类型的 5 包装成一个 Integer 对象,然后再赋值给 num 。
这一切都发生得如此自然,您甚至都感觉不到魔法的存在。
再来说说自动拆箱。
这就像是把那个穿上华丽外衣的数字又脱下来,变回原来简单朴素的样子。
比如说,您有一个 Integer 对象 `num` ,然后您要进行一些数学运算,像 `int result = num + 5;` 。
这时候,自动拆箱就登场啦!它会悄悄地把`num` 这个对象变回基本数据类型的整数,然后再进行加法运算。
是不是感觉特别贴心?就好像有个小精灵在背后默默地为您服务,让您的编程变得轻松又愉快。
自动装箱和自动拆箱可给咱们编程带来了不少方便呢!以前没有它们的时候,咱们得自己手动去做这些转换,麻烦得要死。
现在有了这两个小魔法,代码写起来那叫一个流畅,效率也提高了不少。
比如说,在集合框架里,像 ArrayList 这种东西,它可只能装对象。
要是没有自动装箱,您想把一个整数放进去,那可就得自己先手动把它变成对象,多累呀!有了自动装箱,您直接把整数往里扔就行,简单又省事。
不过呢,虽然自动装箱和自动拆箱很方便,但也不是完全没有缺点的。
装箱和拆箱C++ > C#:在C/C++中不存在类似概念。
需要这两个概念是因为值类型和引用类型都是从Object类派生的这一事实。
而C/C++中没有这样的类。
C#:作为方法局部变量的值类型的实例是直接存储在线程栈上的。
在本线程中使用这些值类型实例无需通过指针或者引用。
有些方法所需的参数是引用类型Object类。
所有值类型都从Object类派生。
但是值类型的实例没有引用。
需要一种方案可以在需要时获取一个值类型实例的引用。
这种方案就是本节要讨论的内容,它称为装箱。
10.7.1 装箱这里有一个实际的例子揭示了我们面对的问题。
代码中的f(函数接受一个Object 类型的引用。
本来我们不能将没有引用的参数传递给它,比如一个int型整数:例10-9可是这个小程序竟然能够编译而且运行起来一切正常。
正是装箱的魔力让我们获取了一个本来没有引用的值类型实例的引用!装箱操作是分三步完成的。
a 该值类型创建了一个新实例,并且分配在堆中。
b 这个堆中的实例根据栈中实例的状态进行初始化。
在这个例子中我们的整数进行了一次四字节的复制。
也可以说初始的对象实例被克隆了一份。
c 用指向新创建的实例的引用取代了原先在栈中分配的实例。
这个程序的Main(函数编译为如下的IL代码。
我们看到IL语言专门为装箱操作提供了box指令。
这条指令将新实例的引用置于运算栈顶。
10.7.2 装箱导致的危险问题如果很在意性能问题的话,那么应当明白装箱操作并不是没有代价的。
在例10-10中有两次装箱操作而在例10-11中只有一次,因此后者会更有效一些。
抛开性能的因素不说,这两个程序的行为也不尽相同,第一个程序显示“Difference references”,而第二个程序显示“Same references”。
这样的优化可能会很危险因为它十分隐秘地改变了程序的行为。
因此不建议采用这种优化。
例10-10例10-1110.7.3 拆箱装箱操作的相反操作称为拆箱。
装箱跟拆箱的概念装箱和拆箱是物流行业中非常重要的概念,它们涉及到货物的包装、运输和处理,对于保障货物的安全和有效进行运输具有重要意义。
在这篇文章中,我将深入解释装箱和拆箱的概念,以及它们在物流中的作用和意义。
首先,让我们来看一下装箱的概念。
装箱,顾名思义就是把货物放入箱子或其他包装容器中,以便进行运输或储存。
在装箱过程中,我们需要考虑到货物的性质、尺寸、重量以及运输方式等因素,选择合适的包装容器,并采取相应的包装方式,确保货物在运输途中不受损坏或丢失。
装箱工作需要有经验和技巧,以确保货物能够安全地到达目的地,减少货物损坏的风险。
装箱的重要性不言而喻。
首先,它可以保护货物免受损坏或丢失。
良好的包装可以有效地减少货物在运输途中受到的冲击和摩擦,避免货物因碰撞或挤压而损坏。
其次,装箱可以提高货物的运输效率。
合适的包装容器和包装方式可以使货物更加紧凑和整齐地摆放,减少货物在运输途中的体积和重量,从而减少运输成本。
此外,装箱还可以提升货物的形象和品质。
精美的包装不仅可以增加货物的吸引力,还可以给客户留下好的印象,提高客户的满意度和信任度。
接下来,让我们转到拆箱的概念。
拆箱就是把货物从包装容器中取出的过程。
在货物到达目的地后,我们需要进行拆箱操作,将货物从包装容器中取出,并进行相应的处理和存放。
拆箱工作同样也是需要技巧和经验的,以避免货物在拆箱过程中受到损坏。
拆箱的作用和意义也是不可或缺的。
首先,拆箱可以让货物得到妥善的处理和存放。
在货物到达目的地后,我们需要对货物进行检查、分类和存放,以保证货物的安全和完整。
其次,拆箱可以帮助我们对货物进行质量和数量的核对。
通过拆箱操作,我们可以及时发现货物的异常和问题,进行相应的处理和解决。
同时,拆箱也是供应链管理中的一个重要环节,对于货物的流通和分配有着重要的作用。
总的来说,装箱和拆箱是物流行业中不可或缺的两个环节,它们对于保障货物的安全和有效进行运输具有重要意义。
合理、科学地进行装箱和拆箱工作,可以有效地降低货物在运输途中的风险,提高货物运输的效率和质量。
装箱和拆箱的方法
装箱和拆箱是我们在日常生活中经常会遇到的事情。
装箱时,首
先要将所要装入物品按照大小、形状分类,然后选择适合大小的箱子。
在装入物品时,要注意轻重物品分开装,重物品放在下面,轻物品放
在上面,并且要将物品摆放整齐,以免在运输中损坏。
当箱子装满时,还要在箱子内部填充一些松软的物品,如泡沫塑料和纸板等,以保护
物品不受震动和摩擦。
拆箱时,首先要小心打开箱子的封条,然后慢慢将箱盖打开。
在
拆箱时,要特别注意不要将封条割坏,以免影响以后的使用。
当箱子
打开后,我们需要按照物品的分类,一个一个地将物品取出,并且按
照原来的摆放方式整齐地放置。
在拆箱过程中,还要注意不要采用过
激的方式将箱子拆开,以免损坏箱子和物品。
在Java中,装箱和拆箱是指将基本类型和对应的包装类之间进行相互转换的过程。
装箱(Boxing)是指将基本类型转换为对应的包装类的过程。
在Java中,包装类通常是以大写字母开头的类,如Integer、Double、Boolean等。
通过装箱,我们可以将基本类型值转换为相应的包装类对象,从而可以调用包装类中的方法或使用包装类中的属性。
拆箱(Unboxing)是指将包装类转换为对应的基本类型的过程。
通过拆箱,我们可以将包装类对象转换为相应的基本类型值,从而可以对其进行操作。
下面是一个示例,演示了装箱和拆箱的过程:
java复制代码
int num = 10;
Integer i = num; // 装箱
double result = i.doubleValue(); // 调用包装类方法
int num2 = (int) result; // 拆箱
在上面的示例中,将基本类型int转换为对应的包装类Integer,这是装箱过程。
然后,调用包装类方法doubleValue(),将包装类对象转换为double类型,这是拆箱过程。
最后,将double类型的result转换为int类型,这是再次拆箱的过程。
需要注意的是,在Java中,自动装箱和自动拆箱可以简化装箱和拆箱的过程。
自动装箱是指将基本类型转换为对应的包装类对象,自动拆箱是指将包装类对象转换为对应的基本类型值。
乘用车集装箱装箱与拆箱作业要求乘用车集装箱装箱与拆箱作业是指将乘用车运输至目的地,将车辆装入或从集装箱中取出的作业过程。
在进行乘用车集装箱装箱与拆箱作业时,需要严格遵守以下要求:1. 安全操作:在进行装箱与拆箱作业时,操作人员必须穿着适当的个人防护装备,包括安全手套和防滑鞋。
操作过程中要确保操作区域平整稳固,并确保没有其他物体妨碍操作的空间。
操作人员应该熟悉操作规程,遵循安全操作流程,确保操作过程安全可靠。
2. 装箱作业要求:在进行装箱作业时,操作人员需要将乘用车以最合适的方式安全装入集装箱中。
首先,清理集装箱内部,确保无杂物和障碍物。
然后,将车辆轻轻驶入集装箱,确保车辆与箱壁之间有足够的空间,以避免损坏。
车辆的四个轮子应与集装箱底部牢固接触,以确保车辆的稳定性。
最后,固定车辆,使用适当的固定工具,如吊索和钢索,将车辆稳固地固定在集装箱内。
3. 拆箱作业要求:在进行拆箱作业时,操作人员需要小心谨慎地从集装箱中取出乘用车。
首先,检查集装箱的固定工具,如吊索和钢索,确保车辆被安全固定。
然后,使用适当的工具拆除固定物,并小心地将车辆从集装箱中取出。
在拆箱过程中,要确保不会损坏车辆或集装箱。
最后,清理集装箱内部,确保无杂物残留,并将集装箱妥善存放。
4. 箱内通风与防潮:为了保护乘用车的质量和状况,乘用车集装箱应具备良好的通风与防潮设备。
集装箱内应安装通风口,确保空气流通,防止车辆在长途运输过程中受潮受损。
同时,集装箱内应使用防潮剂或干燥剂,以吸收潮气,保持干燥环境。
5. 清洁与维护:在装箱与拆箱作业结束后,操作人员应清理集装箱内部,确保没有乱丢的垃圾或杂物,以便下次使用。
同时,集装箱应进行定期的清洁和维护,以保持其良好的状态。
总之,乘用车集装箱装箱与拆箱作业要求严格遵守安全操作流程,小心谨慎地进行作业。
操作人员需要掌握正确的技巧和方法,确保乘用车在装箱与拆箱过程中不受损坏,并保持集装箱的清洁与通风状态。
.Net常见面试题整理(二)——装箱和拆箱为了防止不提供原网址的转载,特在这里加上原文链接:/zhangkai2237/archive/2013/03/21/2974570.html上一节我们讨论的是值类型和引用类型, 我们知道值类型是一种轻量级的数据结构, 对于一些简单的类型定义为值类型会减少定义成引用类型造成的系统开销以及GC的压力。
但是值类型有一个缺点,就是缺少对象指针,我们不能用一个新的变量来引用栈上的值类型(Note:即未装箱的值类型)。
也就是说很多引用类型为参数的方法不能传入值类型。
为了解决这个问题,CLR提供了装箱和拆箱的机制。
一、装箱和拆箱的概念和原理在面试中, 面试官提到装箱和拆箱的问题时,可能很多人想到的第一句话是“装箱是将值类型转化为引用类型的过程;拆箱是将引用类型转化为值类型的过程”。
这句话没有问题,但是仅仅只说出这句话而没有下文的话那就不是一个中级.Net程序员的水平。
实际上装箱和拆箱这个名字就很形象,“箱”指的就是托管堆,装箱即指在托管堆中将在栈上的值类型对象封装,生成一份该值类型对象的副本,并返回该副本的地址。
而拆箱即是指返回已装箱值类型在托管堆中的地址(注意:严格意义来说拆箱是不包括值类型字段的拷贝的)。
如果上面一段你仍然看的不是很明白的话,那么我们来看看装箱和拆箱过程中内部发生的事情。
#region装箱和拆箱int i = 10;object o = i; //装箱int j = (int)o; //拆箱#endregion上面这段代码有一次拆箱和一次装箱。
装箱的过程为:1. 分配内存: 在托管堆中分配好内存,内存的大小是值类型的各个字段需要的内存量加上托管堆的所有对象都有的两个额外成员—类型对象指针和同步块索引—所需要的内存量之和。
2. 复制对象: 将值类型的字段复制到新分配的内存中。
3. 返回地址: 将已装箱的值类型对象的地址返回给引用类型的变量。
我们来看看装箱的IL代码:装箱操作有一个非常明显的标志,就是“box”,它的执行就是完成了我们刚才所说的三步。
装箱和拆箱的概念
装箱和拆箱两个词肯定让很多人十分陌生,但它确实是建筑领域里非常重要的
一部分内容。
装箱和拆箱分别涉及建筑物的建设阶段和拆除阶段,由于建筑物永久或短期移动,两者极为重要。
装箱指的是将建筑物从一个点搬移到另一点,而拆箱就是将建筑物从建造完毕
的位置拆除。
装箱过程中,把建筑物上的部件系统、电气系统和部分机械元件组合起来,在指定土地中建造好,将该建筑物实体移至别处,经过装箱后,建筑物将在被移动到新地方后重新建筑。
然而,拆箱却是整个过程的反向操作,在拆箱处理中,建筑物部件系统、水暖
系统、电气系统和一些元件会被依次拆除,以便将建筑物有机的拆开,通过装卸而正常恢复。
说白了,装箱和拆箱本质上是一个建筑物移动的过程,它的正确完成是当前建
筑行业的重要发展趋势,例如,它可用于临时性建筑物的迁移、永久性建筑物的搬迁、需要维修的大楼、困扰城市道路的桥梁扩建、古代建筑维护和保护等专业领域。
装箱和拆箱是建筑领域里比较不为人知但又极其重要的一门学问,它蕴含着非
常多的技术概念,需要建筑工程师拥有丰富的经验,经过多年从业积累,才能开展正确有效地装箱和拆箱操作。
举例说明装箱和拆箱的作用。
在编程领域中,装箱和拆箱是一种常见的数据转换方式,可以让代码更加灵活和高效。
装箱指的是将一个值类型(如int、double等)转换成对应的引用类型(如object),这样可以把值类型的数据存储在堆上,从而更好地支持泛型等特性。
例如,我们可以把一个整数装箱成一个object 对象,然后把这个对象传递给一个要求参数为object类型的方法,这样做的好处是避免了写多个重载方法来支持不同的参数类型,代码更加简洁。
拆箱则是把一个引用类型(如object)转换成对应的值类型(如int、double等),这个过程需要进行类型检查和转换操作。
在某些情况下,我们需要从一个对象中取出其原始类型的值,例如对于一个存储了整型值的object对象,我们需要把它拆箱成int类型,以便进行数值计算或比较操作。
这个过程中需要保证object对象实际上是一个包含了整型值的对象,否则会抛出异常。
装箱和拆箱在程序中的应用非常广泛,例如在集合类、LINQ查询、反射、属性和委托等方面都有涉及。
然而,由于涉及到类型转换和内存分配等操作,过度使用装箱和拆箱会带来一些性能问题。
因此,在编程时需要根据具体情况谨慎使用,以确保代码的健壮性和高效性。
总之,装箱和拆箱在编程中的作用是非常重要的,它为我们提供了一种灵活和高效的方式来处理值类型和引用类型之间的转换,是我们必须掌握的基本技能之一。
减少装箱(Boxing)和拆箱(Unboxing)操作为了便于⽂章的开展,⾸先介绍装箱(Boxing)和拆箱(Unboxing)这两个名词。
.Net的类型分为两种,⼀种是值类型,另⼀种是引⽤类型。
这两个类型的本质区别,值类型数据是分配在栈中,⽽引⽤类型数据分配在堆上。
那么如果要把⼀个值类型数据放到堆上,就需要装箱操作;反之,把⼀个放在堆上的值类型数据取出来,则需要进⾏拆箱操作。
例如,对于如下简单的装箱和拆箱操作语句。
int i = 123;object obj = i;//Boxingif( obj is int )int j = (int) obj;//Unboxing为了,更好的诠释装箱和拆箱操作,我借⽤MSDN关于“Boxing”的解释图,具体如下。
明⽩了这两名词的意思,现在说说为什么要减少装箱和拆箱操作。
原因有两个,主要是关于效率:⼀个就是对于堆的操作效率⽐较低;另⼀个就是对于堆上分配的内存资源,需要GC来回收,从⽽降低程序效率。
考虑到这两点因素,那么需要在程序中减少装箱和拆箱操作。
如何减少呢,涉及到这两个操作⽐较多的是,格式化输出操作,例如:String.Format,Console.WriteLine之类的语句。
例如:Console.WriteLine( "Number list:{0}, {1}, {2}",1,2,3 );对于“1,2,3”来说,相当于前⾯的“123”⼀样,需要经过装箱和拆箱两个操作。
那么如何避免呢,其实只要向WriteLine传递引⽤类型数据即可,也就是按照如下的⽅式。
Console.WriteLine( "Number list:{0}, {1}, {2}",1.ToString(),2.ToString(),3.ToString() );由于“1.ToString()”的结果是String类型,属于引⽤类型,因此不牵扯装箱和拆箱操作。
代码实现装箱和拆箱在编程中,装箱(boxing)和拆箱(unboxing)是指将值类型(value type)转换为引用类型(reference type)和将引用类型转换为值类型的过程。
这两个概念在C#、Java等编程语言中非常常见,对于理解这一概念的原理和实现方式非常重要。
本文将详细介绍装箱和拆箱的概念、原理以及在C#中的具体实现方式。
1. 装箱(Boxing)装箱是将值类型转换为引用类型的过程。
在C#中,所有的数据类型可以分为值类型和引用类型两种。
值类型包括整型、浮点型、字符型等基本数据类型,而引用类型则包括类、接口、委托等。
在进行装箱操作时,会将值类型的值封装到一个对象中,并将该对象的引用赋给一个引用类型变量。
装箱的过程可以通过以下代码进行演示:int i = 10;object obj = i; // 装箱操作,将int类型转换为object类型在上述代码中,我们将一个int类型的值赋给了一个object类型的变量,这就是一个装箱操作。
装箱操作将值类型的值封装为一个引用类型的对象。
装箱操作的实现原理是创建一个新的对象,将值类型的值复制到这个新对象中,并返回这个新对象的引用。
由于装箱操作涉及到对象的创建和复制,所以会带来一定的性能损耗。
2. 拆箱(Unboxing)拆箱是将引用类型转换为值类型的过程。
在C#中,装箱后的对象可以通过拆箱操作将其转换为原始的值类型。
拆箱操作需要明确指定目标值类型,并且需要确保装箱前的对象类型与拆箱后的值类型相匹配,否则会抛出异常。
拆箱的过程可以通过以下代码进行演示:object obj = 10;int i = (int)obj; // 拆箱操作,将object类型转换为int类型在上述代码中,我们将一个object类型的对象转换为了int类型的值,这就是一个拆箱操作。
拆箱操作将引用类型的对象转换为原始的值类型。
拆箱操作的实现原理是将引用类型对象中存储的值复制到一个新的值类型变量中,并将这个新变量返回。
深⼊理解C#装箱和拆箱(整理篇)装箱(boxing)和拆箱(unboxing)是C#类型系统的核⼼概念.是不同于C与C++的新概念!,通过装箱和拆箱操作,能够在值类型和引⽤类型中架起⼀做桥梁.换⾔之,可以轻松的实现值类型与引⽤类型的互相转换,装箱和拆箱能够统⼀考察系统,任何类型的值最终都可以按照对象进⾏处理.装箱和拆箱是值类型和引⽤类型之间相互转换是要执⾏的操作。
1. 装箱在值类型向引⽤类型转换时发⽣2. 拆箱在引⽤类型向值类型转换时发⽣//1、// 装箱和拆箱是⼀个抽象的概念//2、// 装箱是将值类型转换为引⽤类型;拆箱是将引⽤类型转换为值类型// 利⽤装箱和拆箱功能,可通过允许值类型的任何值与Object 类型的值相互转换,将//值类型与引⽤类型链接起来//例如:int val = 100;object obj = val;Console.WriteLine (“对象的值 = {0}", obj);//这是⼀个装箱的过程,是将值类型转换为引⽤类型的过程int val = 100;object obj = val;int num = (int) obj;Console.WriteLine ("num: {0}", num);//这是⼀个拆箱的过程,是将值类型转换为引⽤类型,再由引⽤类型转换为值类型的过程//注:被装过箱的对象才能被拆箱//3、// .NET中,数据类型划分为值类型和引⽤(不等同于C++的指针)类型,与此对应,内//存分配被分成了两种⽅式,⼀为栈,⼆为堆,注意:是托管堆。
// 值类型只会在栈中分配。
// 引⽤类型分配内存与托管堆。
// 托管堆对应于垃圾回收。
//4:装箱/拆箱是什么?//装箱:⽤于在垃圾回收堆中存储值类型。
装箱是值类型到 object 类型或到此值类型所实//现的任何接⼝类型的隐式转换。
//拆箱:从 object 类型到值类型或从接⼝类型到实现该接⼝的值类型的显式转换。
C#中的装箱与拆箱现在已经很少使⽤ArrayList与Hashtable,除去取数据不⽅便之外,在加⼊元素以及其余操作时,花费的时间也是⽐较多的,效率低;对其解释涉及到装箱和拆箱的问题;⼀、什么是装箱和拆箱装箱:将数值类型转换成引⽤类型的值拆箱:将引⽤类型转换成数值类型int n = 10;object o = n;//装箱int nn = (int)o;//拆箱⼆、装箱与拆箱的判别string str = "123";int a = Convert.ToInt32(str);上述代码,虽然是由引⽤类型转换成值类型;但是并没有发⽣任何的装箱和拆箱的操作;⾸先应该判断两者是否是继承关系,在判断是否是拆箱和装箱;上述代码中,string类型与Int类型并不是继承关系,所以不存在装箱和拆箱的关系;int b = 1233;IComparable c = b;上述代码发⽣了装箱,⾸先int类型与IComparable类型是继承关系;int继承IComparable,⼜是由值类型转换成引⽤类型,所以发⽣了装箱;三、检验装箱操作的效率第⼀组:ArrayList arraylist = new ArrayList();Stopwatch sw = new Stopwatch();sw.Start();for (int i=0;i<1000000;i++){arraylist .Add(i);}sw.Stop();Console.WriteLine(sw.Elapsed);输出:00:00:00.0427016第⼆组:List<int> list = new List<int>();Stopwatch sw = new Stopwatch();sw.Start();for (int i=0;i<1000000;i++){list.Add(i);}sw.Stop();Console.WriteLine(sw.Elapsed);输出:00:00:00.0111906第⼀组代码耗时长⼀些,因为发⽣了装箱;arrayList.Add();中的参数是Object类型的,输⼊的是int类型,所以发⽣了由值类型到引⽤类型的转换;所以以后在写代码的过程中,尽量避开装箱和拆箱操作,这样会降低效率;。
什么是装箱和拆箱2009-06-06 09:36装箱和拆箱:任何值类型、引用类型可以和object(对象)类型之间进行转换。
装箱转换是指将一个值类型隐式或显式地转换成一个object类型,或者把这个值类型转换成一个被该值类型应用的接口类型(interface-type)。
把一个值类型的值装箱,就是创建一个object实例并将这个值复制给这个object,装箱后的object对象中的数据位于堆中,堆中的地址在栈中。
被装箱的类型的值是作为一个拷贝赋给对象的。
如:int i = 10;object obj = i; //隐式装箱object obj = object(i; //显式装箱if(obj is int //int Console.WriteLine(“OK”; Console.WriteLine(obj.GetType(; //System.Int32 有两种方式来查看包装以后的引用对象中包装的原始数据的类型。
要判断原始类型是否是某个给定的原子类型,用is;如果要返回一个字符串,可以用object类的GetType方法。
拆箱转换是指将一个对象类型显式地转换成一个值类型,或是将一个接口类型显式地转换成一个执行该接口地值类型。
注意装箱操作可以隐式进行但拆箱操作必须是显式的。
拆箱过程分成两步:首先,检查这个对象实例,看它是否为给定的值类型的装箱值。
然后,把这个实例的值拷贝给值类型的变量。
比如:int i = 10;object obj = i;int j = (intobj;有两种方式来查看包装以后的引用对象中包装的原始数据的类型。
要判断原始类型是否是某个给定的原子类型,用is;如果要返回一个字符串,可以用object类的GetType方法。
拆箱转换是指将一个对象类型显式地转换成一个值类型,或是将一个接口类型显式地转换成一个执行该接口地值类型。
注意装箱操作可以隐式进行但拆箱操作必须是显式的。
拆箱过程分成两步:首先,检查这个对象实例,看它是否为给定的值类型的装箱值。
装箱就是把值类型转变为引用类型 Integer i = 10; 拆箱就是把引用类型转变为值类型 int i = new Integer(10); 我们现在知道了,所有对象型的数据类型的基类是 ng.Object .而写 java 程序 的时候非常多的工作都是在写这些类,和实现里面的方法。
而偏偏就有那么8种基本类型和 他们不一样。
以至于让你来回在这两种之间转换, 这是很让人头疼的事情。
Java 中 int, long, char 这样的类型不是对象型。
因此 java 里提供了一种叫做包装类(wrapper)的东西,使 基本类型,有着相应的对象类型 Integer,Long,Character 等。
这样就可以,先把基本类 型的东西,转成对象来用,然后再转回去。
来来回回,千锤百炼。
到了 jdk5.0的时候呢,就不用了。
看下面的例子: 实践: 实践:public class Test1 { public static void main(String[] args) { //装箱 int i = 0; Integer integer = i;//i 这么一个基本类型的数,可以赋值给 Integer 型的变量 //简单的拆箱 int j = integer;//integer 这种原始类型的数,也能赋值给 j 这个原始类型的变量Integer counter = 1; int counter2 = counter;//装箱 //拆箱while (counter < 100) { System.out.println("计数 "+counter++); //看啊,counter 这个对象型的数, 还能自动增加 } } }在幕后 JVM 已经自动执行了转换, 同理 Boolean 和 boolean 之间也可以, 自动拆箱装箱。
但是,Integer 和 int 毕竟还是有着不同的。
看下面例子: 看下面例子:public class Test2 { public static void main(String[] args) { Integer i1 = 256; Integer i2 = 256;if (i1 = = i2) System.out.println("相等!"); else System.out.println("不相等!"); } }结果输出的是“不相等!”,两个对象比较,它们在内存中开辟的是两个地址怎么能相 等呢? 警告:你可千万不能依赖这个结果,请把 i1和 i2的值,改成100.(请看 Test3.java) 看看什么结果,令人惊讶的是改了个数,居然输出了“相等!”。
这是因为 JVM 可以选择要尝试这段代码的最佳优化, 并对两个 Integer 对象使用一个实 例,这样的话“= =”就会返回 true 了。
在自动装箱时对于值从–128到127之间的值,使 用一个实例。
这种装箱与拆箱机制对,程序流程控制语句,也有很大影响:public class Test4 { public static void main(String[] args) { Boolean arriving =true; Integer peopleInRoom = 0; int maxCapacity = 100;while (peopleInRoom < maxCapacity) { if (arriving) { System.out.printf("很高兴见到你.%d 号先生\n",peopleInRoom); peopleInRoom++;} else { peopleInRoom--; } }}}另外一个从 unboxing 获得好处的语句是 switch.在 jdk5.0之前的 JVM, switch 接受 int、 short、character 或者 byte 值,而在 unboxing 的操作中,你现在也可以为它赋予新引入 的 enum 之外的 Integer,Short,Char 以及 Byte 值。
Enum 的值,我们在后面的教程会详细 讲述。
Java JDK:自动装箱和拆箱浏览次数: 8 次 字体:[增加 减小] 类型:转载 基本数据(Primitive)类型的自动装箱(autoboxing)、拆箱(unboxing)是自 J2SE 5.0开始提 供的功能。
虽然为您打包基本数据类型提供了方便,但提供方便的同时表示隐藏了细节,建 议在能够区分基本数据类型与对象的差别时再使用。
autoboxing 和 unboxing在 Java 中,所有要处理的东西几乎都是对象 (Object),例如之前所使用的 Scanner 是对象,字符串(String)也是对象,之后还会看到更多的对象。
然而基本(Primitive)数据 类型不是对象,也就是您使用 int、double、boolean 等定义的变量,以及您在程序中直接 写下的字面常量。
在前一个小节中已经大致看到了操作对象的方便性,而使用 Java 有一段时间的人都知 道,有时需要将基本数据类型转换为对象。
例如使用 Map 对象要操作 put()方法时,需要传 入的参数是对象而不是基本数据类型。
要使用打包类型(Wrapper Types)才能将基本数据类型包装为对象,前一个小节中您已 经知道在 J2SE 5.0之前,要使用以下语句才能将 int 包装为一个 Integer 对象:Integer i nteger = new Integer(10);在 J2SE 5.0之后提供了自动装箱的功能,您可以直接使用以下语句来打包基本数据类 型:Integer integer = 10;在进行编译时,编译器再自动根据您写下的语句,判断是否进行自动装箱动作。
在上例 中 integer 参考的会是 Integer 类的实例。
同样的动作可以适用于 boolean、byte、short、 char、long、float、double 等基本数据类型,分别会使用对应的打包类型(Wrapper Types) Boolean、Byte、Short、Character、Long、Float 或 Double。
下面直接使用自动装箱功能 来改写范例 4.4。
范例4.5AutoBoxDemo.javapublic class AutoBoxDemo { public static void main(String[] args) { Integer data1 = 10; Integer data2 = 20; // 转为 double 值再除以3 System.out.println(data1.doubleValue() / 3); // 进行两个值的比较 System.out.println(pareTo(data2)); } }程序看来简洁了许多,data1与 data2在运行时就是 Integer 的实例,可以直接进行对 象操作。
执行的结果如下: 3.3333333333333335 –1自动装箱运用的方法还可以如下: int i = 10; Integer integer = i;也可以使用更一般化的 ng.Number 类来自动装箱。
例如: Number number = 3.14f;3.14f 会先被自动装箱为 Float,然后指定给 number。
JDK:自动装箱和拆箱[3] Java JDK:自动装箱和拆箱[3] 作者:佚名 来源:网络 2009年1月11日 发表评论 进入社区3.14f 会先被自动装箱为 Float,然后指定给 number。
从 J2SE 5.0开始可以自动装箱,也可以自动拆箱(unboxing),也就是将对象中的基本 数据形态信息从对象中自动取出。
例如下面这样写是可以的:Integer fooInteger = 10; int fooPrimitive = fooInteger;fooInteger 引用至自动装箱为 Integer 的实例后,如果被指定给一个 int 类型的变量 fooPrimitive,则会自动变为 int 类型再指定给 fooPrimitive。
在运算时,也可以进行自 动装箱与拆箱。
例如:Integer i = 10; System.out.println(i + 10); System.out.println(i++);上例中会显示20与10,编译器会自动进行自动装箱与拆箱,也就是10会先被装箱,然后 在 i + 10时会先拆箱,进行加法运算;i++该行也是先拆箱再进行递增运算。
再来看一个例 子:Boolean boo = true; System.out.println(boo && false);同样的 boo 原来是 Boolean 的实例,在进行 AND 运算时,会先将 boo 拆箱,再与 false 进行 AND 运算,结果会显示 false。
JDK:自动装箱和拆箱[2] Java JDK:自动装箱和拆箱[2] 作者:佚名 来源:网络 2009年1月11日 发表评论 进入社区范例 AutoBoxDemo.java public class AutoBoxDemo { public static void main(String[] args) { Integer data1 = 10; Integer data2 = 20; // 转为 double 值再除以3 System.out.println(data1.doubleValue() / 3); // 进行两个值的比较 System.out.println(pareTo(data2)); } }程序看来简洁了许多,data1与 data2在运行时就是 Integer 的实例,可以直接进行对 象操作。
执行的结果如下:3.3333333333333335 –1自动装箱运用的方法还可以如下:int i = 10; Integer integer = i;也可以使用更一般化的 ng.Number 类来自动装箱。
例如:Number number = 3.14f;JDK:自动装箱和拆箱[3] Java JDK:自动装箱和拆箱[3] 作者:佚名 来源:网络 2009年1月11日 发表评论 进入社区3.14f 会先被自动装箱为 Float,然后指定给 number。
从 J2SE 5.0开始可以自动装箱,也可以自动拆箱(unboxing),也就是将对象中的基本 数据形态信息从对象中自动取出。
例如下面这样写是可以的:Integer fooInteger = 10; int fooPrimitive = fooInteger;fooInteger 引用至自动装箱为 Integer 的实例后,如果被指定给一个 int 类型的变量 fooPrimitive,则会自动变为 int 类型再指定给 fooPrimitive。