引用型別和值型別
1.值型別
值型別包括:數值型別,結構體,bool型,使用者定義的結構體,列舉,可空型別。
值型別的變數直接儲存資料,分配在託管棧中。變數會在建立它們的方法返回時自動釋放。
所有的值型別都是密封(seal)的,所以無法派生出新的值型別。
2.引用型別
引用型別包括:陣列,使用者定義的類、介面、委託,object,字串,null型別,類。
引用型別的變數持有的是資料的引用,資料儲存在資料堆,分配在託管堆中,變數並不會在建立它們的方法結束時釋放記憶體,它們所佔用的記憶體會被CLR中的垃圾回收機制釋放。
CLR常用簡寫詞語,CLR是公共語言執行庫(Common Language Runtime)和Java
3.值型別與引用型別區別:
值型別 |
引用型別 |
|
儲存方式 |
直接儲存資料本身 |
儲存的是資料的引用,資料儲存在資料堆中 |
記憶體分配 |
分配在棧中的 |
分配在堆中 |
效率 |
效率高,不需要地址轉換 |
效率較低,需要進行地址轉換 |
記憶體回收 |
使用完後立即回收 |
使用完後不立即回收,而是交給GC處理回收 |
賦值操作 |
建立一個新物件 |
建立一個引用 |
型別擴充套件 |
不易擴充套件,所有值型別都是密封(seal)的,所以無法派生出新的值型別 |
具有多型的特性方便擴充套件 |
例項分配 |
通常是線上程棧上分配的(靜態分配),但是在某些情形下可以儲存在堆中 |
總是在程序堆中分配(動態分配) |
4.適用場合:
值型別在記憶體管理方面具有更好的效率,並且不支援多型,適合用做儲存資料的載體;引用型別支援多型,適合用於定義應用程式的行為。
引用型別可以派生出新的型別,而值型別不能,因為所有的值型別都是密封的。
引用型別可包含null值,值型別不能(可空型別功能允許將null賦給值型別,如int a=null);
引用型別變數的賦值只複製對物件的引用,而不復制物件本身。而將一個值型別變數賦給另一個值型別變數時,將複製包含的值
5.裝箱和拆箱
1)裝箱就是將一個值型別轉換成等值的引用型別
在堆上為新生成的物件(該物件包含資料,物件本身沒有名稱)分配記憶體。
將堆疊上值型別變數的值拷貝到堆上的物件中。
將堆上建立的物件的地址返回給引用型別變數(從程式設計師角度看,這個變數的名稱就好像堆上物件的名稱一樣)。
2)拆箱就是將一個引用型別轉換成等值的值型別
將引用型別變數堆上的值拷貝到棧上面。