欧美成人午夜免费全部完,亚洲午夜福利精品久久,а√最新版在线天堂,另类亚洲综合区图片小说区,亚洲欧美日韩精品色xxx

扣丁學(xué)堂Java培訓(xùn)簡述C#中如何正確的使用字符串String

2019-03-18 11:34:47 7578瀏覽

本篇文章扣丁學(xué)堂Java培訓(xùn)小編和喜歡Java開發(fā)技術(shù)的讀者們分享一下C#中如何正確的使用字符串String,對Java開發(fā)感興趣或者是想要參加Java培訓(xùn)進入到Java開發(fā)領(lǐng)域的小伙伴就隨小編一起來學(xué)習一下吧。


扣丁學(xué)堂Java培訓(xùn)簡述C#中如何正確的使用字符串String


言:


C#中提供了比較全面的字符串處理方法,很多函數(shù)都進行了封裝為我們的編程工作提供了很大的便利。System.String是最常用的字符串操作類,可以幫助開發(fā)者完成絕大部分的字符串操作功能,使用方便。


字符串作為所有編程語言中使用最頻繁的一種基礎(chǔ)數(shù)據(jù)類型。如果使用不慎,將會造成不必要的內(nèi)存開銷,為此而付出代價。



而要優(yōu)化此類型,從以下兩點入手:


1、盡量少的裝箱

2、避免分配額外的內(nèi)存空間



先從第一點裝箱的操作說起,查看如下代碼:


//發(fā)生裝箱的代碼
String boxOperate = "test" + 4.5f;


其中間語言IL代碼為如下:


IL_0000: nop
IL_0001: ldstr "test"
IL_0006: ldc.r4 4.5
IL_000b: box [mscorlib]System.Single
IL_0010: call string [mscorlib]System.String::Concat(object, object)
IL_0015: stloc.0
IL_0016: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
IL_001b: pop
IL_001c: ret


不難看出,上述代碼發(fā)生了裝箱的操作(IL代碼中的box).裝箱之所以會發(fā)生性能損耗,因為它要完成如下三個步驟:


1、首先,會為值類型在托管堆中分配內(nèi)存。除了值類型本身所分配的內(nèi)存外,內(nèi)存總量還要加上類型對象指針和同步塊索引所占用的內(nèi)存,

2、將值類型的值復(fù)制到新分配的堆內(nèi)存中。

3、返回已經(jīng)成為引用類型的對象的地址。



在來看以下代碼:


//沒有發(fā)生裝箱的代碼
String boxOperate = "test" + 4.ToString();


其中間IL代碼如下:


IL_0000: nop
IL_0001: ldstr "test"
IL_0006: ldc.r4 4
IL_000b: stloc.1
IL_000c: ldloca.s 1
IL_000e: call instance string [mscorlib]System.Single::ToString()
IL_0013: call string [mscorlib]System.String::Concat(string, string)
IL_0018: stloc.0
IL_0019: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
IL_001e: pop
IL_001f: ret


如上,并沒有發(fā)生任何裝箱操作,但是達到的結(jié)果卻是我們想要的。原因是 4.ToString() 這行代碼并沒有發(fā)生裝箱行為,是實際調(diào)用的是整數(shù)型的ToString()方法,其原型如下:


public override string ToString(){
return Number.FormatInt32(m_value, null, NumberFormat.CurrentInfo);
}


可能有人會問,是不是原型中的 Number.Format_XXX方法會發(fā)生裝箱行為呢?實際上,Number.Format_XXX方法是一個非托管的方法,其原型如下:


[MethodImpl(MethodImplOptions.InternalCall), SecurityCritical]
public statuc extern string FormatInt32(int value, string format,NumberFormatInfo info);


它是通過直接操作內(nèi)存來完成 Int32 到 String 的轉(zhuǎn)換,效率要比裝箱高得多。所以,在使用其他值引用類型到字符串得轉(zhuǎn)換比完成拼接時,應(yīng)當避免使用操作符 “+” 來我完成,而應(yīng)該使用值引用類型提供得ToString方法。


也許有人會問:即使FCL提供得方法沒有發(fā)生裝箱行為,但在其他情況下,F(xiàn)CL方法內(nèi)部會不會含有裝箱的行為?也許會存在,所以,本人推薦:編寫代碼中,應(yīng)當盡量避免發(fā)生不必要的裝箱代碼。



第二個方面:避免分配額外的空間。對于CLR來說,String對象(字符串對象)是個很特殊的對象,它一旦被賦值就不可改變(在內(nèi)存中)。在運行時調(diào)用System.String類中的任何方法或進行任何運算('=‘賦值,'+‘拼接等),都會在內(nèi)存中創(chuàng)建一個新的字符串對象,這也意味著要為該新對象分配新的內(nèi)存空間。如以下代碼會帶來額外開銷。


private static void Test(){
String str1 = "aa";
str1 = str1 + "123" + "345";
//以上代碼創(chuàng)建了3個String對象,并執(zhí)行了一次String.Contact方法。
}


而在以下代碼中,字符串不會在運行時拼接字符串,而是會在編譯時直接生成一個字符串。


private static void Test()
{
String str= "aa" + "123" + "345";//等效 String str= "aa123345";
}
private static void Test2()
{
const String str = "aa";
String newStr = "123" + str;
//因為str是一個常量,所以該代碼等效于 String newStr = "123" + “aa”;
//最終等效于 String newStr = "123aa”;
}


由于使用System.String類會在某些場合帶來明顯的性能損耗,所以微軟另外提供了一個類型StringBuilder來彌補String的不足。


StringBuilder并不會重新創(chuàng)建一個String對象,它的效率源于預(yù)先以非托管的方式分配內(nèi)存。如果StringBuilder沒有先定義長度,則默認分配的長度為16。當StringBuilder的長度大于16小于32時,StringBuild又會重新分配內(nèi)存,使之成為16的倍數(shù)。StringBuilder重新分配內(nèi)存時按照上次的容量加倍進行分配的。注意:StringBuilder指定的長度要合適,太小了,需要頻繁分配內(nèi)存;太大了,浪費內(nèi)存空間。



以下是例子舉例:



private static String Test3()
{
String a = "t";
a += "e";
a += "s";
a += "t";
return a;
}
private static String Test4()
{
String a = "t";
String b = "e";
String c = "s";
String d = "t";
return a + b + c + d;
}
//以上兩種效率都不高效。不要以為前者比后者創(chuàng)建的字符串對象更少,事實上,兩者創(chuàng)建的字符串對象相等
//且前者進行了3次的String.Contact方法調(diào)用,比后者還多了兩次。



要完成上圖的運行時的字符串拼接(注意:是運行時),更佳的做法是使用StringBuilder類型,代碼如下:



private static String Test5()
{
String a = "t";
String b = "e";
String c = "s";
String d = "t";
StringBuilder sb = new StringBuilder(a);
sb.Append(b);
sb.Append(c);
sb.Append(d);
return sb.ToString();
//因為說的是運行時,所以沒必要使用以下代碼
//StringBuilder sb = new StringBuilder("t");
//sb.Append("e");
//sb.Append("s");
//sb.Append("t");
//return sb.ToString();
}



微軟還提供了另外一個來簡化這種操作,即使用String.Format 方法。String.Format方法在內(nèi)部使用StringBuilder 進行字符串格式化,如下代碼:



private static String Test6()
{
//為演示,定義4個變量
String a = "t";
String b = "e";
String c = "s";
String d = "t";
return String.Format("{0}{1}{2}{3}", a, b, c, d);
}



結(jié):


在使用String字符串時,應(yīng)該盡量避免裝箱操作和“+”連接操作。



最后想要了解更多Java方面內(nèi)容的小伙伴可以登錄扣丁學(xué)堂官網(wǎng)咨詢,扣丁學(xué)堂有專業(yè)老師制定的Java學(xué)習路線圖輔助學(xué)員學(xué)習,此外還有與時俱進的Java視頻教程供大家學(xué)習哦,想要學(xué)好Java開發(fā)技術(shù)的同學(xué)請加入扣丁學(xué)堂Java技術(shù)交流群:670348138。


扣丁學(xué)堂微信公眾號

【關(guān)注微信公眾號獲取更多學(xué)習資料】



查看更多關(guān)于“Java開發(fā)資訊”的相關(guān)文章>>




標簽: 參加Java培訓(xùn)學(xué)習靠譜嗎 Java培訓(xùn) Java基礎(chǔ)教程 Java學(xué)習視頻 Java教學(xué)視頻 java入門教程 Java教程視頻 java在線學(xué)習 java在線視頻 java在線教程

熱門專區(qū)

暫無熱門資訊

課程推薦

微信
微博
15311698296

全國免費咨詢熱線

郵箱:codingke@1000phone.com

官方群:148715490

北京千鋒互聯(lián)科技有限公司版權(quán)所有   北京市海淀區(qū)寶盛北里西區(qū)28號中關(guān)村智誠科創(chuàng)大廈4層
京ICP備2021002079號-2   Copyright ? 2017 - 2022
返回頂部 返回頂部