新聞中心
最近在園子里看到幾篇關(guān)于string的文章,感覺其中有一些誤解,不知道是自己理解有誤還是園友理解錯(cuò)誤,也沒發(fā)現(xiàn)有園友提出質(zhì)疑,索性也將自己的一點(diǎn)理解寫出來,也對(duì)一些質(zhì)疑提出了自己的解釋,不管怎樣我希望如果是我哪里理解錯(cuò)誤大家一定要提出來,我們一起進(jìn)步,否則真的會(huì)誤導(dǎo)很多人,也感覺到寫文章是要負(fù)責(zé)任的,否則就干脆寫日志,不要發(fā)表出來誤導(dǎo)到了一些對(duì).Net不熟悉的朋友!

創(chuàng)新互聯(lián)公司服務(wù)項(xiàng)目包括上饒網(wǎng)站建設(shè)、上饒網(wǎng)站制作、上饒網(wǎng)頁制作以及上饒網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,上饒網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到上饒省份的部分城市,未來相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
1.在DoNet中String是不可改變的,什么叫不可變呢,首先大家先看下面的例子:
string a = "1"; 而是創(chuàng)建了一個(gè)新的字符串; 所以String的不可變就是當(dāng)你在創(chuàng)建了字符串后其不可修改; |
2.當(dāng)創(chuàng)建多個(gè)字符串內(nèi)容相同的對(duì)象時(shí),都只會(huì)指向同一個(gè)引用;
string a = "11"; |
a和b都指向同一個(gè)a的引用,并不會(huì)為b重新分配內(nèi)存;這樣即可保證內(nèi)存有效利用;這一點(diǎn)用IL不是很好看出來,所以大家可以按下面方法去比較他們的引用地址,都是指向同一個(gè)堆;
Console.WriteLine(string.ReferenceEquals(a, b)); |
運(yùn)行結(jié)果:
True |
這說明當(dāng)我們新建一個(gè)字符串以后,將為其分配內(nèi)存,而之后如何有值和其相同的字符串不會(huì)被創(chuàng)建分配堆而是直接分配其引用;
3.字符串比較:
==和!=是為了比較String對(duì)象的值是否相同而不是比較引用;
例如等號(hào)首先是比較引用是否相同,因?yàn)橐孟嗤狄欢〞?huì)相同,就避免了再去對(duì)值進(jìn)行比較;
而引用如果不同再去比較值,相同則返回true;
總之==一定一定是為了比較字符串的值是否相同;
string s2 = new StringBuilder().Append("My").Append("Test").ToString();
|
上面是返回False,大家肯定有些迷惑,而此前一位園友則解釋我也不盡贊同,這里只發(fā)表我的解釋:
此處比較的是兩個(gè)引用類型,為什么這么說,因?yàn)榇蠹叶贾酪玫刂范际谴娣旁跅V?而此處正是將存放在棧中的引用地址裝箱轉(zhuǎn)換成了引用類型也就是分別創(chuàng)建了兩個(gè)值為引用地址的堆,而他們引用地址的值肯定不一樣,所以結(jié)果顯然就是False了;
4.為什么總是提倡使用StringBuilder對(duì)象;
如果用String,每進(jìn)行一次字符串的拼接就要分配一個(gè)新的堆,如果只有一兩次倒無所謂,如果頻繁如此操作性能會(huì)很差;但StringBuilder是在為其分配的堆上做修改,不會(huì)重新分配,所以性能比String拼接字符串好;相信大家理解上面幾點(diǎn)了我這里也純粹是廢話了,呵呵!
5.***就是看到有人提到Intern方法,我感覺他們對(duì)此方法具體功能理解不透徹存在誤解;
首先看下面例子:
static void Main(string[] args) |
先看***個(gè)Main,我根據(jù)***個(gè)Main來解釋:
如果傳遞給Intern的是一個(gè)變量的引用地址,那么他會(huì)檢索是否用與此引用地址所指向的堆的值相同的其他堆,如果有他會(huì)返回此堆的引用地址,也就是a。
我們再來看第二個(gè)Main來繼續(xù)解釋:
如果沒有找到與所指向的堆的值相同的其他堆,他將返回b的引用地址;
***看第三個(gè)Main做***解釋:
如果傳遞進(jìn)去的是字符串而不是引用地址,他一樣會(huì)檢索是否存在與此字符串相同的堆,如果有則返回此堆的引用地址,如無則駐留此字符串并返回其引用地址;
而這里所將的駐留也是String的特殊之處,字符串在被創(chuàng)建后不會(huì)被立即回收,即使已不存在對(duì)其引用;他會(huì)在被創(chuàng)建之后一直駐留在內(nèi)存中直至程序結(jié)束,大家可以查看MSDN解釋,下面將拿出一些MSDN的解釋來配合說明一下;
其中=>符號(hào)的是我做的注釋:
------MSDN解釋--Start------------------------------------------------------------------------------------
在1.1中
string str1 = String.Empty;
string str2 = String.Intern(String.Empty);
if ((object) str1) == ((object) str2);
...
==>是返回false,但在2.0中返回true,所以更加證實(shí)了如上所說;下面主要是講解了String的拘留池概念,大家理解上面概念后相信理解他也不成問題;
公共語言運(yùn)行庫通過維護(hù)一個(gè)表來存放字符串,該表稱為拘留池,它包含程序中以編程方式聲明或創(chuàng)建的每個(gè)唯一的字符串的一個(gè)引用.因此,具有特定值的字符串的實(shí)例在系統(tǒng)中只有一個(gè).例如,如果將同一字符串分配給幾個(gè)變量,運(yùn)行庫就會(huì)從拘留池中檢索對(duì)該字符串的相同引用,并將它分配給各個(gè)變量.Intern 方法使用拘留池來搜索與 str 值相等的字符串.如果存在這樣的字符串,則返回拘留池中它的引用。
如果不存在,則向拘留池添加對(duì) str 的引用,然后返回該引用.如果要減少應(yīng)用程序分配的內(nèi)存總量,請(qǐng)記住留用字符串有兩個(gè)不希望出現(xiàn)的副作用:首先,為留用的 String 對(duì)象分配的內(nèi)存在公共語言運(yùn)行庫 (CLR) 終止之前不大可能釋放.這是因?yàn)?CLR 對(duì)留用的 String 對(duì)象的引用可能保持到應(yīng)用程序終止之后,甚至可能保持到應(yīng)用程序域終止之后.其次,要留用字符串,必須先創(chuàng)建字符串.即使 String 對(duì)象使用的內(nèi)存最終將通過垃圾回收,仍然必須分配該內(nèi)存.
上面就說到了[為留用的 String 對(duì)象分配的內(nèi)存在公共語言運(yùn)行庫 (CLR) 終止之前不大可能釋放.]
.NET Framework 2.0 版引入了 CompilationRelaxations.NoStringInterning 枚舉成員.
NoStringInterning 成員將程序集標(biāo)記為不需要字符串拘留.可以使用 CompilationRelaxationsAttribute 屬性將NoStringInterning 應(yīng)用于某個(gè)程序集.使用本機(jī)映像生成器 (Ngen.exe) 將該程序集安裝到本地計(jì)算機(jī)上的本機(jī)映像緩存時(shí),不使用字符串拘留.這里所提到的本機(jī)映像可以改善內(nèi)存使用情況,大家可以查MSDN詳細(xì)了解;
【編輯推薦】
- 詳解Java String字符串對(duì)象的創(chuàng)建及管理
- String對(duì)象的理解進(jìn)行時(shí)
- 在.NET程序中正確使用String類型
網(wǎng)頁名稱:你真的理解正確String某些特性了嗎?
分享地址:http://www.dlmjj.cn/article/dpschjp.html


咨詢
建站咨詢
