最近學習到字符串,整理了一下String,StringBuffer,StringBuilder相關知識
### 1. String
String 類位于 java.lang 包中。String 對象創建后則不能被修改,是不可變的,所謂的修改其實是創建了新的對象,所指向的內存空間不同。
~~~
String str1 = "xiaosi";
str1 = "歡迎你 " + str1;
System.out.println(str1); // 歡迎你 xiaosi
~~~
通過觀察運行結果可以看見str1變量輸出確實改變了,但是為什么一直說String對象是不可變的呢? 我們其實被表象給欺騙了,JVM是這樣解析這段代碼的:首先創建對象str1,賦予xiaosi,然后再創建一個新的對象用來執行第二行代碼,str1指向了這個新對象,原對象沒有發生改變,由于這種機制,每當用String操作字符串時,實際上是在不斷的創建新對象,而原來的對象就會變為垃圾被GC回收掉。

這樣做是否會降低運行效率呢?看起來好像修改一個代碼單元要比創建一個新字符串更加簡潔。答案是:也對,也不對。通過拼接"歡迎你"和"xiaosi"來創建一個新字符串的效率確實不高。但是,不可變字符卻有一個有點:編譯器可以讓字符串達到共享。
為了弄清楚具體的工作方式,可以想象將各種字符串放入公共的字符串存儲池中,字符串變量指向字符串存儲池中相應位置。如果復制一個字符串變量,原始字符串與復制的字符串變量共享相同的字符。
Java設計者認為共享帶來的高效率遠遠勝于提取,拼接字符串所帶來的低效率。查看一下程序你就會發現:很少需要修改字符串,而是往往需要對字符串進行比較。
### 2.StringBuffer
String和StringBuffer他們都可以存儲和操作字符串,即包含多個字符的字符串數據。String類是字符串常量,是不可更改的常量。而StringBuffer是字符串變量,它的對象是可以擴充和修改的。
~~~
// 創建一個空的StringBuffer類的對象。
public StringBuffer()
// 創建一個長度為 參數length 的StringBuffer類的對象。
public StringBuffer( int length )
~~~
其是線程安全的可變字符序列。一個類似于 String 的字符串緩沖區。可將字符串緩沖區安全地用于多個線程。可以在必要時對這些方法進行同步,因此任意特定實例上的所有操作就好像是以串行順序發生的,該順序與所涉及的每個線程進行的方法調用順序一致。
StringBuffer 上的主要操作是 append 和 insert 方法,可重載這些方法,以接受任意類型的數據。每個方法都能有效地將給定的數據轉換成字符串,然后將該字符串的字符添加或插入到字符串緩沖區中。append 方法始終將這些字符添加到緩沖區的末端;而 insert 方法則在指定的點添加字符。
每個字符串緩沖區都有一定的容量。只要字符串緩沖區所包含的字符序列的長度沒有超出此容量,就無需分配新的內部緩沖區數組。如果內部緩沖區溢出,則此容量自動增大。
### 3.StringBuilder
從 JDK 5 開始,為該類補充了一個單個線程使用的等價類,即 StringBuilder。StringBuffer和StringBuilder類功能基本相似,主要區別在于StringBuffer類的方法是多線程、安全的,而 StringBuilder不是線程安全的。與該類相比,通常應該優先使用 StringBuilder 類,因為它支持所有相同的操作,但由于它不執行同步,所以速度更快。對于經常要改變值的字符串應該使用 StringBuffer和StringBuilder類。
### 4.總結
(1)一般情況下,速度從快到慢:StringBuilder > StringBuffer > String,這種比較是相對的,不是絕對的。?
(2)當字符串緩沖被多個線程使用時,JVM不能保證StringBuilder的操作是安全的,雖然速度快,但是StringBuffer是可以保證是正確操作的。大多數情況下是在單線程下進行的操作,所以大多數情況下是建議用StringBuilder而不用StringBuffer的。
- 前言
- [Hibernate開發之路](1)Hibernate配置
- [Hibernate開發之路](2)Hibernate問題
- [Hibernate開發之路](3)基礎配置
- [Hibernate開發之路](4)ID生成策略
- [Hibernate開發之路](5)聯合主鍵
- [設計模式實踐之路](1)單例模式
- [Java]UDP通信的簡單例子
- [Java]套接字地址InetAddress講解
- [Java開發之路](1)final關鍵字
- [Java開發之路](2)Java字符串
- [Java開發之路](3)Java常用類
- [Java開發之路](4)String、StringBuffer與StringBuilder詳解
- [Java開發之路](5)異常詳解
- [Java開發之路](6)File類的使用
- [Java開發之路](7)RandomAccessFile類詳解
- [Java開發之路](8)輸入流和輸出流
- [Java開發之路](9)對象序列化與反序列化
- [Java開發之路](10)DOM解析XML文檔
- [Java開發之路](11)SAX解析XML文檔
- [Java開發之路](12)JDOM和DOM4J解析XML文檔
- [Java開發之路](14)反射機制
- [Java開發之路](15)注解
- [Java開發之路](16)學習log4j日志
- [Java開發之路](18)關于Class.getResource和ClassLoader.getResource的路徑問題
- [Java開發之路](19)Long緩存問題
- [Java開發之路](20)try-with-resource 異常聲明
- [Java開發之路](21)Comparator與Comparable
- [Java]Java工程師成神之路
- [細說Java](1)圖說字符串的不變性
- [細說Java](2)Java中字符串為什么是不可變的
- [細說Java](3)創建字符串是使用" "還是構造函數?