维纳斯
在程序中寻找自由与成就感~~~~

前言:下面先看一段程序,通过程序来引入拆箱和装箱的概念:

1.装箱

int i=42;

Object o=i;

i=50;

Console.WriteLine(“i={0},o={1}”,i ,o);//输出为i=50,o=42

下面分析一下为什么会是这个结果。

实际情况是:首先从内存堆栈中分配一小片内存,来存储int类型的数据42,然后再分配一小片内存来存储一个引用o。接着在内存堆中分配一片内存,将i中值的一个副本存在在该内存中。最后让i的引用指向这个副本。这种将一个数据项从堆栈自动复制到堆得行为成为装箱(Boxing)。

若修改一个变量的原始值,不会修改堆上现有的值,因为它只是一个副本。

先将图附上,方便理解:

2.拆箱

   int i=42;

   object o=i;//装箱

   i=(int)o;//成功编译,为了访问已装箱的值,必须进行一次强制类型转换。

   编译器发现指定了类型int,所以在运行时生成代码来检查o实际引用的时什么,它能引用任何东西。假如o真的引用一个已装箱的int,而且一切条件都满足强制类型转换,就会成功执行,编译器生成的代码会从装箱的int中提取出值,这个过程成为拆箱。

  如果o没有引用一个已装箱的int,就会出现类型不配的情况,造成强制类型转换失败。

  Circle c=new Circle(42);

  Object o=c;//不装箱,Circle是一个类

  int i=(int)o;//编译成功,但是在运行时会抛出异常,抛出InvalidCastException异常

拆箱时指定的类型必须与装箱的类型完全一致,假定装箱时容纳的是一个int值的副本,并试图拆箱成一个long,就会抛出异常,虽然隐式类型转换能将int转换成long,但这个约定在这是不成立的。注意:拆箱时类型必须完全匹配。

以上就是我对拆箱和装箱的浅见。

posted on 2012-11-23 13:45  维纳斯  阅读(265)  评论(0编辑  收藏  举报