當把一個值類型賦值給引用類型,這個過程可以看作是"裝箱"。
object a = 10;
以上,堆棧上的過程大致是:1、在棧上開辟空間給變量a2、在堆上開辟空間,習慣上把該空間看作是"箱子"3、把10"裝箱"
變量a指向堆上值為10的對象,換句話說,變量a的值是堆上對象的地址。
現在,如果我們想讓a=11,可能首先想到的是:讓"箱子"內的10自增1,變成11。
嘗試這樣做:
結果報錯:++無法運用于object類型。也就是說,++無法應用于引用類型。oject a = 10;a++;
那好辦,先拆箱變成值類型,然后自增1呢?
結果還是報錯:增量或減量運算符的操作數必須為變量、屬性或索引器。((int)a)++,相當于10++,相當于10=10+1,相當于10=11,難怪會報錯!object a = 10;((int)a)++;
好吧,++幫不了我們,但我們可以把拆箱后的值賦值給另外一個變量:
這樣,a的值就是11了。object a = 10;int temp = (int)a;a = temp + 1;
這次,堆棧上大致是這樣:1、在棧上開辟空間給變量a2、在堆上開辟空間,習慣上把該空間看作是"箱子"3、把10"裝箱"4、在棧上開閉空間給變量temp5、把a的值拆箱后,賦值給變量temp,此時temp的值為106、在堆上又開辟另外的空間7、把temp + 1,即11裝箱
變量指向堆上值為11的對象。堆上值為10的對象則等待GC的回收。
當然,以上的做法是"曲線救國",完全可以這樣:
之所以這樣繞,是因為想在原先值的基礎上得到新的值。object a = 10;a = 11;
最后,回到本篇的主題:值類型裝箱后能改變其值嗎?答案是不能。裝箱后的值具有"恒定性(Immutable)"的特點。就像本篇中的object a = 10,如果想給引用類型變量a賦上新的值,就直接a=11,就可以了。10一旦裝箱,就無法改變其值了。
新聞熱點
疑難解答