装箱拆箱(转)

偶今天看JDK5的时候也发现了装箱/拆箱概念,遂作一总结,以备后用。
.net中有一个很重要的概念,装箱与拆箱,之后在jdk5也出现了自动装箱/拆箱的概念。偶对此表一下自己的理解。
一、什么时装箱/拆箱。
这要涉及到数据类型,在.net中所有的类型都继承自System.Object,所有的类型都是对象.类型主要分为两种,一是值类型,包括原类型(Sbyte、Byte、Short、Ushort、Int、Uint、Long、Ulong、Char、Float、Double、Bool、Decimal)、枚举(enum)、结构(struct).另一类是引用类型,包括类、数组、接口、委托、字符串等.
其中值类型是在栈中分配内存,本身的声明就是一个初始化的过程,其不需要进行垃圾回收,只要超出所定义的作用范围会自动释放内存.
而引用类型则是在堆中分配的,和java一样,在堆种分配内存,而其托管堆进行垃圾回收.
当两种数据类型进行转换时就引出了装箱/拆箱.
装箱:值类型到引用类型或到此值类型所实现的任何接口类型的隐式转换
例如: int temp = 3;
System.Object obj = temp;
其中,temp为值类型,在栈中分配;当分配obj这个引用类型时,我们需要在堆中分配一个obj对象,然后把temp值赋给它,这么一系列的过程就是装箱的过程。
拆箱:从引用类型到任意值类型的显式转换。与装箱不同,拆箱式显示装换。
例如:int temp = 3;
System.Object obj = temp;
int i = (int) obj;
拆箱过程中,首先来确定对象obj为一个值类型的装箱值,然后把值赋给值类型。
加个例子强化一下理解,西西
int temp = 3;
object obj = temp;
Console.WriteLine (temp + "," + (int) obj);
在此过程中,进行了3次装箱和1次拆箱;很明显,obj = temp时第一次装箱,temp + "," + (int) obj中,temp要先转换为String类,第2次装箱,(int)obj第3次装箱成引用类型。obj转换为int时拆箱。
二、评价装箱/拆箱。
装箱和拆箱虽然满足了两只类型之间的转换。但是从装箱的过程中不难看出,每次装箱时要在堆中new一个新的对象,当量特别大是肯定会大大影响程序的效率。事物总有两面性,every sword has two sides,事情便简单了,性能也下来了。所以,在应用中,我们应该尽量避免装箱操作。
三、对装箱/拆箱更进一步的了解
最后引用一个例子,摘自http://blog.csdn.net/tiger119/archive/2006/08/28/1134068.aspx
装箱/拆箱并不如上面所讲那么简单明了,比如:装箱时,变为引用对象,会多出一个方法表指针,这会有何用处呢?
我们可以通过示例来进一步探讨。
举个例子。
Struct A : ICloneable
{
public Int32 x;
public override String ToString() {
return String.Format("{0}",x);
}
public object Clone() {
return MemberwiseClone();
}
}
static void main()
{
A a;
a.x = 100;
Console.WriteLine(a.ToString());
Console.WriteLine(a.GetType());
A a2 = (A)a.Clone();
ICloneable c = a2;
Ojbect o = c.Clone();
}
5.0:a.ToString()。编译器发现A重写了ToString方法,会直接调用ToString的指令。因为A是值类型,编译器不会出现多态行为。因此,直接调用,不装箱。(注:ToString是A的基类System.ValueType的方法)
5.1: a.GetType(),GetType是继承于System.ValueType的方法,要调用它,需要一个方法表指针,于是a将被装箱,从而生成方法表指针,调用基类的System.ValueType。(补一句,所有的值类型都是继承于System.ValueType的)。
5.2:a.Clone(),因为A实现了Clone方法,所以无需装箱。
5.3:ICloneable转型:当a2为转为接口类型时,必须装箱,因为接口是一种引用类型。
5.4:c.Clone()。无需装箱,在托管堆中对上一步已装箱的对象进行调用。
附:其实上面的基于一个根本的原理,因为未装箱的值类型没有方法表指针,所以,不能通过值类型来调用其上继承的虚方法。另外,接口类型是一个引用类型。对此,我的理解,该方法表指针类似C++的虚函数表指针,它是用来实现引用对象的多态机制的重要依据。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值