裝箱和拆箱 深度理解

2022-02-06 16:59:27 字數 2092 閱讀 4223

提問:

首先我們來提兩個疑問,我們自定義了乙個類如customclass型別,

customclass myclass=new customclass()

object obj=myclass;

執行上面這段**,我們會進行裝箱操作嗎?

基礎知識:

.net的型別分為兩種,一種是值型別(value type ),另一種是引用型別(reference type)。這兩個型別的本質區別,值型別資料是分配在棧中,而引用型別資料分配在堆上。那麼如果要把乙個值型別資料放到堆上,就需要裝箱操作;反之,把乙個放在堆上的值型別資料取出來,則需要進行拆箱操作。

說到具體程式**上, 我們可以這樣總結: 裝箱是將值型別轉換為引用型別 ;拆箱是在已裝箱的前提下將引用型別轉換為值型別.

我們要充分的了解裝箱和拆箱,首先我們先得了解一下.net framework平台的類的構造.在這個平台上有乙個萬物之源,那就是system.object型別,在之下系統又分了值型別(value type )和引用型別(reference type).

值型別包括原型別(sbyte、byte、short、ushort、int、uint、long、ulong、char、float、double、bool、decimal)、列舉(enum)、結構(struct),引用型別包括:類、陣列、介面、委託、字串等。所以到這裡我們就可以得出乙個結論,文章開頭提的那個問題的答案也就不言而喻了.我們自定義宣告的型別是一種引用型別,所以我們把他放到object裡面的時候,是不會發生裝箱操作的.

具體操作:

下面我們來解析一下裝箱和拆箱系統做了那些操作

前面我們已經說到.值型別資料是分配在棧(stack)中,他是乙個先進後出的結構,由編譯器自動分配釋放 ,存放函式的引數值,區域性變數的值等.而引用型別資料分配在堆(heap)上,其操作方式類似於資料結構中的棧。堆他是一種順序隨意的結構,一般由程式設計師分配釋放若程式設計師不釋放,程式結束時可能由os** 。注意它與資料結構中的堆是兩回事,分配方式倒是類似於鍊錶。具體在.net框架上的情況你可以閱讀 

.net中棧和堆的比較

這篇文章,這位博主翻譯了四篇關於這方面的文章,為中國的it視野做出了巨大的貢獻啊.

我們來結合乙個小例子說明一下裝箱操作:

int i = 123; object o = (object)i;

對值型別在堆中分配乙個物件例項,並將該值複製到新的物件中。按三步進行。

第一步:新分配堆記憶體(大小為值型別例項大小加上乙個方法表指標和乙個syncblockindex)。

第二步:將值型別的例項字段拷貝到新分配的記憶體中。

第三步:返回堆中新分配物件的位址。這個位址就是乙個指向物件的引用了。

我們通過這種方式將乙個值型別的int i裝箱為乙個object型別的 o變數

拆箱就是乙個逆過程了.將乙個object 型別的o變數還原為int型的i變數,它進行了如下操作:

(1)環境須先判斷堆疊上指向合法物件的位址,以及在對此物件向指定的型別進行轉換時是否合法,如果不合法,就丟擲異常;

(2)當判斷型別轉換正確,就返回乙個指向物件內的值的指標。

針對上面的合法性判斷,有兩點需要我們注意:

(1)包含已裝箱的值型別的引用的變數如果為null,就丟擲乙個nullreferenceexception異常。

(2)如果引用指向的物件不是所要求的值型別的乙個已裝箱的例項,就丟擲乙個invaildcastexception異常

帶來的影響:

我們可以從兩個方面考慮:

乙個就是對於堆的操作效率比較低;另乙個就是對於堆上分配的記憶體資源,需要gc來**,從而降低程式效率。

顯然,直觀的來說.裝箱時,生成的是全新的引用物件,這會有時間損耗,也就是造成效率降低。

當然我們也可以直觀的看出,拆箱所帶來的效能損失是遠小於裝箱所帶來的損失的.

ok.已經很晚了,明天再來發一篇文章主要介紹我們在程式設計中怎麼解決裝箱拆箱帶來的效能損失.各位晚安.

裝箱和拆箱的理解

裝箱 boxing 和拆箱 unboxing 是c 型別系統的核心概念.是不同於c與c 的新概念!通過裝箱和拆箱操作,能夠在值型別和引用型別中架起一做橋梁.換言之,可以輕鬆的實現值型別與引用型別的互相轉換,裝箱和拆箱能夠統一考察系統,任何型別的值最終都可以按照物件進行處理.c 語言中的所有型別都是由...

裝箱和拆箱,自動裝箱和自動拆箱

以integer的建立為例。裝箱 把基本資料型別轉換成包裝類物件 int integer integer num1 new integer 17 拆箱 把乙個包裝類的物件,轉換成基本型別的變數 integer int int num2 num1.intvalue 自動裝箱 integer num3 ...

C 裝箱 拆箱 理解

裝箱和拆箱是值型別和引用型別之間相互轉換是要執行的操作。1.裝箱在值型別向引用型別轉換時發生 2.拆箱在引用型別向值型別轉換時發生 光上述兩句話不難理解,但是往深處了解,就需要一些篇幅來解釋了。我們先看裝箱時都會發生什麼事情,下面是一行最簡單的裝箱 objectobj 1 這行語句將整型常量1賦給o...