搜尋
首頁後端開發C#.Net教程String StringBuffer StringBuilder 區別

String 字串常數 
StringBuffer 字串變數(線程安全) 
StringBuilder 字串變數(非線程安全) 
簡要的說, String 類型和StringBuffer 類型的主要效能區別其實在於String 是不可變的物件, 因此在每次對String 類型改變的時候其實都等於產生了一個新的String 對象,然後將指標指向新的String 對象,所以經常改變內容的字串最好不要用String ,因為每次產生物件都會對系統效能產生影響,特別當記憶體中無引用物件多了以後, JVM 的GC 就會開始運作,那速度是一定會相當慢的。 
而如果是使用 StringBuffer 類別則結果就不一樣了,每次結果都會對 StringBuffer 物件本身進行操作,而不是產生新的對象,再改變物件參考。所以在一般情況下我們推薦使用 StringBuffer ,特別是字串物件經常改變的情況下。而在某些特別情況下, String 物件的字串拼接其實是被JVM 解釋成了StringBuffer 物件的拼接,所以這些時候String 物件的速度不會比StringBuffer 物件慢,而特別是以下的字串物件生成中, String 效率是遠要比StringBuffer 快的: 
String S1 = “This is only a” + “ simple” + “ test”; 
StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple ”).append(“ test”); 
你會很驚訝的發現,生成String S1 物件的速度簡直太快了,而這個時候StringBuffer 居然速度上根本一點都不佔優勢。其實這是JVM 的把戲,在JVM 眼裡,這個 
String S1 = “This is only a” + “ simple” + “test”; 其實是: 
String S1 = “This is only a simple test”; 所以當然不需要太多的時間了。但大家這裡要注意的是,如果你的字串是來自另一個的String 物件的話,速度就沒那麼快了,譬如: 
String S2 = “This is only a”; 
String S3 = “ simple”; 
String S4 = “ test”; 
String S1 = S2 +S3 + S4; 
這時候JVM 會規規矩矩的按照原來的方式去做 

在大部分情況下StringBuffer > String 
StringBuffer 
.線程安全的可變字元序列。一個類似 String 的字串緩衝區,但不能修改。雖然在任意時間點上它都包含某種特定的字元序列,但透過某些方法呼叫可以改變該序列的長度和內容。 
可將字串緩衝區安全地用於多個執行緒。可以在必要時對這些方法進行同步,因此任意特定實例上的所有操作就好像是以串行順序發生的,該順序與所涉及的每個線程進行的方法調用順序一致。 
StringBuffer 上的主要操作是 append 和 insert 方法,可重載這些方法,以接受任意類型的資料。每個方法都能有效地將給定的資料轉換成字串,然後將該字串的字元追加或插入到字串緩衝區中。 append 方法始終將這些字元新增至緩衝區的末端;而 insert 方法則在指定的點新增字元。
例如,如果z 引用一個當前內容是“start”的字串緩衝區對象,則此方法調用z.append("le") 會使字串緩衝區包含“startle”,而z.insert(4, "le") 將更改字串緩衝區,使其包含「starlet」。 
在大部分情況下 StringBuilder > StringBuffer 
java.lang.StringBuilde 
java.lang.StringBuilder一個可變的字元序列是5.0新增的。此類別提供一個與 StringBuffer 相容的 API,但不保證同步。該類別被設計用作 StringBuffer 的一個簡易替換,用在字串緩衝區被單一執行緒使用的時候(這種情況很普遍)。如果可能,建議優先採用該類,因為在大多數實作中,它比 StringBuffer 更快。兩者的方法基本上相同。
================================================= ======================== 
String類別詳解 
1、String類別是final的,不可被繼承。 
2、String類別是的本質是字元陣列char[], 且其值無法改變。 PRivate final char value[]; 
接著開啟String類別的API文檔,可以發現: 
3、String類別物件有個特殊的建立的方式,就是直接指定例如String x = "abc","abc"就表示一個字串物件。而x是"abc"物件的地址,也叫 

做"abc"物件的引用。 
4、String物件可以透過「+」串連。串聯後會產生新的字串。也可以透過concat()來串聯,這個後面會講述。 
6、Java執行時會維護一個String Pool(String池),JavaDoc翻譯很模糊「字串緩衝區」。 String池用來存放運作時產生的各種字串, 

且池中的字串的內容不重複。而一般物件不存在這個緩衝池,並且所建立的物件僅僅存在於方法的堆疊區。 

其一,使用new關鍵字建立字串,例如String s1 = new String("abc"); 
其二,直接指定。例如String s2 = "abc"; 
其三,使用串連產生新的字串。例如String s3 = "ab" + "c"; 

二、String物件的建立 

String物件的建立也非常講究,關鍵在於明白其原理。
原理1:當使用任何方式來建立一個字串物件s時,Java運行時(運行中JVM)會拿著這個X在String池中找是否存在內容相同的字串對象, 

如果不存在,則在池中建立一個字串s,否則,不在池中新增。 

原理2:Java中,只要使用new關鍵字來建立對象,則一定會(在堆疊區或堆疊區)建立一個新的物件。 

原理3:使用直接指定或使用純字串串聯來建立String對象,則只會檢查維護String池中的字串,池中沒有就在池中建立一個,有則罷 

了!但絕不會在堆疊區再去建立該String物件。 

原理4:使用包含變數的表達式建立String對象,則不僅會檢查維護String池,還會在堆疊區建立一個String物件。 

另外,String的intern()方法是一個本地方法,定義為public native String intern(); intern()方法的價值在於讓開發者能將注意力集中到 

String池上。當呼叫 intern 方法時,如果池已經包含一個等於此 String 物件的字串(該物件由 equals(Object) 方法決定),則傳回池 

中的字串。否則,將此 String 物件新增至池中,並且傳回此 String 物件的參考。 

三、不可變類 
不可改變的字串有一個很大的優點:編譯器可以把字串設定為共享。 
不可變類別String有一個重要的優點-它們不會被分享引用。

是這樣的,JAVA為了提高效率,所以對String類型進行了特別的處理---為string型別提供了串列池 
定義一個string型別的變數有兩種方式: 
string name= "tom ";
string name =new string( "tom ") 
使用第一種方式的時候,就使用了串池, 
使用第二中方式的時候,就是一種普通的聲明對象的方式 
如果你使用了第一種方式,那麼當你在聲明一個內容也是"tom "的string時,它將使用串池裡原來的那個內存,而不會重新分配內存,也就是說,string saname= "tom ",將會指向同一塊記憶體 

另外關於string型別是不可改變的問題: 
string型別是不可改變的,也就是說,當你想改變一個string物件的時候,例如name= "madding " 
那麼虛擬機不會改變原來的對象,而是產生一個新的string對象,然後讓name去指向它,如果原來的那個"tom "沒有任何對象去引用它,虛擬機的垃圾回收機制將接收它。 
據說這樣可以提高效率! ! !
================================================= ========================final StringBuffer a = new StringBuffer("111");  
final StringBuffer b = new StringBuffer("222");  
a=b;//此句編譯不透過  
final StringBuffer a = new StringBuffer("111");  
a.append("222");//編譯透過   
可見,而final只對引用的"值"(即記憶體位址)有效,它迫使引用只能指向初始指向的那個對象,改變它的指向會導致編譯期錯誤。至於它所指向的對象的​​變化,final是不負責的。

String常數池問題的四個例子 
以下是幾個常見例子的比較分析與理解: 

[1]  
String a = "a1";   
String b = "a" + 1; .println((a == b)); //result = true 
String a = "atrue";   
String b = "a" + "true";   
System.out.println((a == b))) ; //result = true 
String a = "a3.4";   
String b = "a" + 3.4;   
System.out.println((a == b)); //result = true  
分析:JVM對於字串常數的"+"號連接,將程式編譯期,JVM就將常數字串的"+"連接最佳化為連接後的值,拿"a" + 1來說,經編譯器最佳化後在class中就已經是a1。在編譯期其字串常數的值就確定下來,故上面程式最終的結果都為true。

[2]  
String a = "ab";   
String bb = "b";   
String b = "a" + bb;   
System.out.print b = "a" + bb;   false  
分析:JVM對於字串引用,由於在字串的"+"連接中,有字串引用存在,而引用的值在程式編譯期是無法確定的,即"a" + bb無法被編譯器最佳化,只有在程式運行期來動態分配並將連接後的新位址賦給b。所以上面程式的結果也就為false。

[3] 
String a = "ab";   
final String bb = "b";  
String b = "a" + bb;   
System.out.println((a ult)); = true  
分析:和[3]中唯一不同的是bb字串加了final修飾,對於final修飾的變量,它在編譯時被解析為常數值的一個本地拷貝存儲到自己的常數池中或嵌入到它的字節碼流中。 
所以此時的"a" + bb和"a" + "b"效果是一樣的。故上面程式的結果為true。

[4]  
String a = "ab";   
final String bb = getBB();   
String b = "a" + bb;   
System
String b = "a" + bb;   
System。 = false   
private static String getBB() {  return "b";   }   
分析:JVM對於字串引用bb,它的值在編譯期間無法確定,只有在程式執行期呼叫方法後,將方法的傳回值與字串和"a"來動態連線並指派位址為b,故上面程式的結果為false。

透過上面4個例子可以得知: 

String  s  =  "a" + "b" + "c";     就等價於String s = "abc" 

String
String  b  =  "b";     
String  c  =  "c";     
String  s  =   a uffer temp = new StringBuffer();     
temp. append(a).append(b).append(c);     
String s = temp.toString();   
由上述分析的結果,因此不難推論出String 採用連結運算子(+)效率低原因分析,形如這樣的程式碼: 

public class Test {  
public static void main(String args[]) {  
String s = null;  
for(int i = 0; i }  
}   
每做一次+ 就產生個StringBuilder對象,而append後就丟掉。下次循環再到達時重新產生個StringBuilder對象,然後 append 字串,如此循環直至結束。 如果我們直接採用 StringBuilder 物件進行 append 的話,我們可以節省 N - 1 次建立和銷毀物件的時間。所以對於在迴圈中要進行字串連接的應用,一般都是用StringBuffer或StringBulider物件來進行append操作。

String物件的intern方法理解與分析 
public class Test4 {  
private static String a = "ab";   
public static void main(String[] args){ 
String s1 = "; b"; 
String s = s1 + s2;  
System.out.println(s == a);//false  
System.out.println(s.intern() == a);//true  }   
這裡用到Java裡面是一個常數池的問題。對於s1+s2操作,其實是在堆裡面重新創建了一個新的物件,s保存的是這個新物件在堆空間的的內容,所以s與a的值是不相等的。而當呼叫s.intern()方法,卻可以傳回s在常數池中的位址值,因為a的值儲存在常數池中,故s.intern和a的值相等。

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
c#.net適合您嗎?評估其適用性c#.net適合您嗎?評估其適用性Apr 13, 2025 am 12:03 AM

c#.netissutableforenterprise-levelapplications withemofrosoftecosystemdueToItsStrongTyping,richlibraries,androbustperraries,androbustperformance.however,itmaynotbeidealfoross-platement forment forment forment forvepentment offependment dovelopment toveloperment toveloperment whenrawspeedsportor whenrawspeedseedpolitical politionalitable,

.NET中的C#代碼:探索編程過程.NET中的C#代碼:探索編程過程Apr 12, 2025 am 12:02 AM

C#在.NET中的編程過程包括以下步驟:1)編寫C#代碼,2)編譯為中間語言(IL),3)由.NET運行時(CLR)執行。 C#在.NET中的優勢在於其現代化語法、強大的類型系統和與.NET框架的緊密集成,適用於從桌面應用到Web服務的各種開發場景。

C#.NET:探索核心概念和編程基礎知識C#.NET:探索核心概念和編程基礎知識Apr 10, 2025 am 09:32 AM

C#是一種現代、面向對象的編程語言,由微軟開發並作為.NET框架的一部分。 1.C#支持面向對象編程(OOP),包括封裝、繼承和多態。 2.C#中的異步編程通過async和await關鍵字實現,提高應用的響應性。 3.使用LINQ可以簡潔地處理數據集合。 4.常見錯誤包括空引用異常和索引超出範圍異常,調試技巧包括使用調試器和異常處理。 5.性能優化包括使用StringBuilder和避免不必要的裝箱和拆箱。

測試C#.NET應用程序:單元,集成和端到端測試測試C#.NET應用程序:單元,集成和端到端測試Apr 09, 2025 am 12:04 AM

C#.NET應用的測試策略包括單元測試、集成測試和端到端測試。 1.單元測試確保代碼的最小單元獨立工作,使用MSTest、NUnit或xUnit框架。 2.集成測試驗證多個單元組合的功能,常用模擬數據和外部服務。 3.端到端測試模擬用戶完整操作流程,通常使用Selenium進行自動化測試。

高級C#.NET教程:ACE您的下一次高級開發人員面試高級C#.NET教程:ACE您的下一次高級開發人員面試Apr 08, 2025 am 12:06 AM

C#高級開發者面試需要掌握異步編程、LINQ、.NET框架內部工作原理等核心知識。 1.異步編程通過async和await簡化操作,提升應用響應性。 2.LINQ以SQL風格操作數據,需注意性能。 3..NET框架的CLR管理內存,垃圾回收需謹慎使用。

C#.NET面試問題和答案:提高您的專業知識C#.NET面試問題和答案:提高您的專業知識Apr 07, 2025 am 12:01 AM

C#.NET面試問題和答案包括基礎知識、核心概念和高級用法。 1)基礎知識:C#是微軟開發的面向對象語言,主要用於.NET框架。 2)核心概念:委託和事件允許動態綁定方法,LINQ提供強大查詢功能。 3)高級用法:異步編程提高響應性,表達式樹用於動態代碼構建。

使用C#.NET建築微服務:建築師實用指南使用C#.NET建築微服務:建築師實用指南Apr 06, 2025 am 12:08 AM

C#.NET是構建微服務的熱門選擇,因為其生態系統強大且支持豐富。 1)使用ASP.NETCore創建RESTfulAPI,處理訂單創建和查詢。 2)利用gRPC實現微服務間的高效通信,定義和實現訂單服務。 3)通過Docker容器化微服務,簡化部署和管理。

C#.NET安全性最佳實踐:防止常見漏洞C#.NET安全性最佳實踐:防止常見漏洞Apr 05, 2025 am 12:01 AM

C#和.NET的安全最佳實踐包括輸入驗證、輸出編碼、異常處理、以及身份驗證和授權。 1)使用正則表達式或內置方法驗證輸入,防止惡意數據進入系統。 2)輸出編碼防止XSS攻擊,使用HttpUtility.HtmlEncode方法。 3)異常處理避免信息洩露,記錄錯誤但不返回詳細信息給用戶。 4)使用ASP.NETIdentity和Claims-based授權保護應用免受未授權訪問。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具