String、StringBuffer和StringBuilder的區(qū)別

今天很大家來聊一下這個(gè)基礎(chǔ)的問題

說他們?nèi)咧g的區(qū)別我總結(jié)為一下三點(diǎn):

1.String長度不可變而StringBuffer和SringBuilder長度可變

2.他們的運(yùn)行速度不同 :SringBuilder > StringBuffer > String

3.SringBuilder 線程不安全 和 StringBuffer線程安全

下面我來一個(gè)一個(gè)解釋:

一.String長度不可變而StringBuffer和SringBuilder長度可變

廢話不多說,先上源碼!

如果你可以打開三個(gè)類的源碼看一下你就明白了

String.png
StringBuffer.png
StringBuilder.png
AbstractStringBuilder.png

我們能看到,String這個(gè)類底層使用了final修飾的長度不可變的字符數(shù)組,所以它長度不可變

private final char value[];

而StringBuffer和StringBuilder 都繼承自AbstractStringBuilder ,且AbstractStringBuilder底層使用的是可變字符數(shù)組,所以二者長度可變。

char[] value;

二.他們的運(yùn)行速度不同 :SringBuilder > StringBuffer > String

先來看這樣一段代碼

public class MainTest {
    public static void main(String[] args) {
        String  str = "abc";
        System.out.println(str);
        str = str + "cd";
        System.out.println(str);
    }
}

輸出結(jié)果為:

abc

abcd

? 整個(gè)程序運(yùn)行完我們看似是str這個(gè)對(duì)象被更改了,在后面加上了一段新的字符,但這只是假象,因?yàn)槲覀儎偛耪f過String類型的字符串長度是不可變的啊,其實(shí)JVM是先創(chuàng)建的了一個(gè)str對(duì)象,將“abc”賦值給str,然后在內(nèi)存中又創(chuàng)建了第二個(gè)str對(duì)象,將第一個(gè)str對(duì)象中的“abc”與”de“相加再賦值給第二個(gè)str對(duì)象,此時(shí)Java虛擬機(jī)的垃圾回收機(jī)制開始其工作將第一個(gè)str對(duì)象回收。所以說String類型的字符串要完成這樣”改變長度“的操作需要不斷地創(chuàng)建再回收,創(chuàng)建再回收,無形中經(jīng)過了很多步驟,而 StringBuffer和SringBuilder數(shù)組可變,直接可進(jìn)行更改,所以要更快。

而SringBuilder 為什么比 StringBuffer 要快呢?

先來看源碼:

BuilderAppend.png
BufferAppend.png

? 從圖中可以看出StringBuffer的append的方法都被toStringCache關(guān)鍵字修飾了(不止圖中這兩個(gè)append方法包括StringBuffer源碼中所有append重載方法都被toStringCache修飾了。)

toStringCache關(guān)鍵字是給線程加鎖,枷鎖是會(huì)帶來性能上的損耗的,故用SringBuilder 比 StringBuffer 要快

鎖不懂先沒關(guān)系,往下看!暫且理解為什么快。

三.SringBuilder 線程不安全 和 StringBuffer線程安全

? 線程安全不同的問題要和剛才的的思路連起來,正是因?yàn)橛辛藅oStringCache關(guān)鍵字修飾StringBuffer的append方法有,給線程加了鎖加了鎖所以線程安全。

? 這樣理解,如果一個(gè)StringBuffer對(duì)象的字符串在字符串緩沖區(qū)被多個(gè)線程同時(shí)使用時(shí),也就是多個(gè)線程同時(shí)操作,這樣會(huì)有出現(xiàn)錯(cuò)誤操作的概率,為了保證線程的安全性,進(jìn)行加鎖,這樣會(huì)使同一時(shí)間只有一個(gè)線程獲得權(quán)限,其他線程必須等待該線程結(jié)束并釋放鎖才能獲得權(quán)限,這樣線程非常安全,雖然效率慢了點(diǎn),但是當(dāng)項(xiàng)目安全性要求很高時(shí)就必須用StringBuffer。單一線程下還是的用更快一點(diǎn)的SringBuilder 。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 四、集合框架 1:String類:字符串(重點(diǎn)) (1)多個(gè)字符組成的一個(gè)序列,叫字符串。生活中很多數(shù)據(jù)的描述都采...
    佘大將軍閱讀 867評(píng)論 0 2
  • 第十天 權(quán)限修飾符 public protected default private 同一類 true true ...
    炙冰閱讀 604評(píng)論 0 1
  • 昨天是蝸牛向上爬的第一天,雖有決心,卻不盡人意。 賓館的空調(diào)冷的要死,旁邊熟睡的隊(duì)友加上自身的懶散,讓我一次又一次...
    要奮斗的蝸牛閱讀 193評(píng)論 0 0
  • 從去年8月份,開始知道冥想這個(gè)概念,到10月3號(hào)正式開始冥想,至今已經(jīng)九個(gè)多月了。 由剛開始的,每天半小時(shí),到后來...
    超級(jí)賦能王張勝萍閱讀 1,870評(píng)論 7 6
  • 0 反思 代碼質(zhì)量永遠(yuǎn)是繞不過去的一個(gè)坎,如今公司人員擴(kuò)招,更多進(jìn)來的是初級(jí)工程師,慢慢意識(shí)到一個(gè)嚴(yán)重的問題,質(zhì)量...
    __XY__閱讀 475評(píng)論 0 0

友情鏈接更多精彩內(nèi)容