拆箱与装箱

来源:互联网 发布:福鼎广电网络客服电话 编辑:程序博客网 时间:2024/05/01 01:43
.net按数据存放的地点将数据分为两种类型
值类型:栈:数字型、字符型、布尔型、结构体等
引用类型:堆:数组、字符串、类
attention: 堆是一种需要手动管理的内存
值类型和引用类型所使用的内存特性不一样,导致两者在使用上也不尽相同。
1 值存在于栈上,存放的是数据值
2 引用类型存于堆上,存放的是地址


他们间的相互转换,有什么实用性??

值型别本身存储其相关的数据,数据在栈中分配;
引用型别本身不存储直接的数据,他存储的是一个内存地址,这个内存地址称为handle,它是具名的,这个内存地址指向我们要引用的对象,这个对象是不具名的,也就是说如果不通过handle,那你就无法访问这个对象,而值就不一样,他可以直接访问。这个不具名的对象是在受控堆(managed heap)中分配。
在内存中表示:
value:   value object(访问值内型,也就是直接访问该值对象)
reference:handle-->object(访问引用型别,必须通过handle来间接访问。)
你只需要记住引用始终是一对handle/object就行了。二者缺一不可,没有前者,就容易造成内存泄露,没有后者,使用引用就会发生异常。
装箱的过程就是:
1在受控堆分配一块空间,准备用来持有值对象的值。
2将值对象的值放在刚分配的空间中
3将该受控堆的地址赋给引用对象,也就是上面说的handle
4如果值对象不再使用,则标识该内存空间为可用,回收空间。如果程序上下文还需要使用它,则在第三步就完成。
折箱是一个相反的过程,但是这个过程要复杂些,有向下转型和安全转型的问题,这个过程中最有用的就是as关键字。

 =====================================================================
 

栈的特点是快速高效,缺点是有限制,数据不灵活;而堆的特点是灵活方便,数据适应面广泛,但是效率有一定降低。栈的内存分配是自动释放,也就没有释放函数。堆空间的分配总是动态的,虽然程序结束时所有的数据空间都会被释放回系统,但是精确的申请内存/释放内存匹配是良好程序的基本要素,在.NET中会有GC来处理内存的释放。

 

除了接口是个例外,通用类型系统中的类型被分为两类:值类型和引用类型。在使用引用类型时会有一些性能上的问题,因此如果一个系统全部用引用类型,则这个系统的性能会大大减弱;因此.NET Framework 设计者保留了struct 数据类型,而在 java 语言中就没有 struct 数据类型。

 

值类型:

            包括基元类型、用户自定义结构或枚举类型

            继承自System.ValueType类型

            在堆栈上分配

            通过拷贝赋值

            默认通过值来传递参数,除非用ref关键字

 

引用类型:

            C#预定义的引用类型包括objectstring类型,用户定义的引用类型可以是接口类型、类类型和委托类型

            继承自System. Object类型

            在托管堆上用“new”关键字分配

            通过引用赋值

            可能出现几个引用指向同一个对象,因此对一个变量的操作会影响另一个变量所引 用的同一对象

            用引用来传递变量

原创粉丝点击