c#中String類型的存儲(chǔ)原理詳解_第1頁(yè)
c#中String類型的存儲(chǔ)原理詳解_第2頁(yè)
c#中String類型的存儲(chǔ)原理詳解_第3頁(yè)
c#中String類型的存儲(chǔ)原理詳解_第4頁(yè)
c#中String類型的存儲(chǔ)原理詳解_第5頁(yè)
全文預(yù)覽已結(jié)束

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第c#中String類型的存儲(chǔ)原理詳解在我們正式了解c#中的String類型前,先來(lái)判斷一下下面代碼的結(jié)果吧~

Stringstr1="123";

Stringstr2=str1;

str2="321";

Console.WriteLine(str1);

上面代碼的最終輸出結(jié)果是123,如果有淺學(xué)過(guò)引用類型的同學(xué)一定會(huì)問(wèn):str2不是在存儲(chǔ)的是str1的引用么?那么str2不是和str1指向堆中同一塊內(nèi)存空間么?為什么在引用了str2使其改變數(shù)據(jù)后再打印出str1最終還是打印出來(lái)123?

這也是我最初的疑問(wèn),但不要著急,一步一步看下去,相信很快能了解清楚。

在正式開(kāi)始之前,我們先了解一下c#中的內(nèi)存分區(qū):

棧區(qū):由編譯器自動(dòng)分配釋放,存放值類型的對(duì)象本身,引用類型的引用地址(指針),靜態(tài)區(qū)對(duì)象的引用地址(指針),常量區(qū)對(duì)象的引用地址(指針)等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。堆區(qū)(托管堆):用于存放引用類型對(duì)象本身。在c#中由.net平臺(tái)的垃圾回收機(jī)制(GC)管理。棧,堆都屬于動(dòng)態(tài)存儲(chǔ)區(qū),可以實(shí)現(xiàn)動(dòng)態(tài)分配。(重點(diǎn)看)靜態(tài)區(qū)及常量區(qū):用于存放靜態(tài)類,靜態(tài)成員(靜態(tài)變量,靜態(tài)方法),常量的對(duì)象本身。由于存在棧內(nèi)的引用地址都在程序運(yùn)行開(kāi)始最先入棧,因此靜態(tài)區(qū)和常量區(qū)內(nèi)的對(duì)象的生命周期會(huì)持續(xù)到程序運(yùn)行結(jié)束時(shí),屆時(shí)靜態(tài)區(qū)內(nèi)和常量區(qū)內(nèi)對(duì)象才會(huì)被釋放和回收(編譯器自動(dòng)釋放)。所以應(yīng)限制使用靜態(tài)類,靜態(tài)成員(靜態(tài)變量,靜態(tài)方法),常量,否則程序負(fù)荷高。代碼區(qū):存放函數(shù)體內(nèi)的二進(jìn)制代碼。

在c#中,String的存儲(chǔ)方式很特殊,在c#的內(nèi)存中,在常量區(qū)里會(huì)分配一塊空間叫做String暫存池(常量池),在某些時(shí)候,我們的字符串?dāng)?shù)據(jù)是存儲(chǔ)在這個(gè)常量池中的,而地址依然是存放在棧中。

例如用Stringstr=xXXXX的方式來(lái)創(chuàng)建String變量的話,那么String的值便會(huì)存儲(chǔ)在String常量池中,在我們以這種方式創(chuàng)建String變量時(shí),編譯器會(huì)先判斷你這個(gè)內(nèi)容有沒(méi)有已經(jīng)在常量池出現(xiàn)過(guò)了,如果已經(jīng)出現(xiàn)過(guò),那么不會(huì)再在常量池中使用空間來(lái)存放一個(gè)相同的內(nèi)容,這個(gè)內(nèi)容只會(huì)固定有一個(gè)引用,所以在創(chuàng)造相同內(nèi)容的String的時(shí)候,他們的引用都是相同的。又有一種情況:一開(kāi)始A和B內(nèi)容相同,就是說(shuō)A與B的引用都相同時(shí),此時(shí)將B的內(nèi)容更改,那么B的內(nèi)容在常量池中就會(huì)使用另一塊空間,那么相應(yīng)的B的引用也會(huì)改變,而A的引用并不會(huì)改變,因?yàn)锳此時(shí)還是存儲(chǔ)的原來(lái)的內(nèi)容。我們可以來(lái)看簡(jiǎn)易的圖解:

以上我們可以用代碼來(lái)證實(shí)我們的結(jié)論:

Stringstr1="123";

Stringstr2="123";

Console.WriteLine("此時(shí)還未將str1中的值做改變:");

if(object.ReferenceEquals(str1,str2))

Console.WriteLine("此時(shí)引用相同");

else

Console.WriteLine("此時(shí)引用不相同");

if(object.ReferenceEquals(String.Intern(str1),String.Intern(str2)))

Console.WriteLine("此時(shí)存儲(chǔ)在同一塊常量池中,且引用相同");

else

Console.WriteLine("此時(shí)兩字符串不相同,存在不同的空間中,且引用也不同");

Console.WriteLine();

str1="12";

Console.WriteLine("此時(shí)將str1的值改變,比較str1與str2的引用和所指向的內(nèi)存空間是否相同:");

if(object.ReferenceEquals(str1,str2))

Console.WriteLine("此時(shí)引用相同");

else

Console.WriteLine("此時(shí)引用不相同");

if(object.ReferenceEquals(String.Intern(str1),String.Intern(str2)))

Console.WriteLine("此時(shí)存儲(chǔ)在同一塊常量池中,且引用相同");

else

Console.WriteLine("此時(shí)兩字符串不相同,存在不同的空間中,且引用也不同");

}

可以看到最終運(yùn)行的結(jié)果:

為了更好理解以上代碼,下面是對(duì)代碼的一些東西的解釋:

object.ReferenceEquals

這個(gè)是用來(lái)比較兩個(gè)變量的引用是否一樣,如果一樣,那么則會(huì)返回true,否則將會(huì)返回false。

String.Intern

String.Intern的工作方式很好理解,你將一個(gè)字符串作為參數(shù)使用這個(gè)接口,如果這個(gè)字符串已經(jīng)存在池中,就返回這個(gè)存在的引用;如果不存在就將它加入到池中,并返回引用。

當(dāng)然,以上只是針對(duì)用Stringstr=XXXXX這樣創(chuàng)建變量的方式來(lái)討論的,那么什么時(shí)候創(chuàng)建String會(huì)考慮這樣的問(wèn)題呢?下面來(lái)看情況總結(jié):

我們要知道不是所有字符串都放在常量池當(dāng)中:

存放暫存池:

用字面量值創(chuàng)建String對(duì)象,例:Stringstr=ABCD用String.Intern(),例:StringBuildersb=newStringBuilder(ABCD);stringstr1=ABCDstringstr2=string.Intern(sb.ToString);字符串拼接,例:str1=ABCD;str2=EFG;str1+str2。

不存放暫存池(存放在堆中):

使用str.Tostring,例:str1=ABCDstr2=str1.ToString();使用char[].Tostring(),例:str1=ABCDchar[]charArray=str1.ToArray();str2=charArray.ToString();使用newString(),例:

str1=”999”;char[]charArray=str1.ToArray();stringstr2=newstring(charArray);stringstr3=newstring(charArray);

char[]charArray={‘A','B'};str1=“ABCDE”;str2=”CDE”+

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論