String(字符串):
? ? ? ?在 Java 中String屬于對(duì)象,Java提供了String類來創(chuàng)建和操作字符串十拣。明哥查找了一下jdk文檔,發(fā)現(xiàn)String對(duì)象是不可被改變的(因?yàn)橛小癴inal”修飾符)
????????那么問題就來了:為什么java中字符串要被設(shè)計(jì)成不可變對(duì)象志鹃?
為什么String被設(shè)計(jì)成不可變對(duì)象夭问?
????1.字符串常量池的需求
????????字符串常量池是方法區(qū)中的一塊特別存儲(chǔ)區(qū)域。當(dāng)需要?jiǎng)?chuàng)建一個(gè)字符串時(shí)曹铃,如果它的值在字符串常量池中已存在缰趋,那么常量池中的該字符串引用將被直接返回,而不會(huì)創(chuàng)建一個(gè)新的字符串對(duì)象返回其引用。
? ??????如果字符串是可變的秘血,那么通過一個(gè)引用改變字符串的值味抖,其它該字符串對(duì)象的引用將得到錯(cuò)誤的值。
????2.緩存Hashcode
????????字符串的hashcode在java中經(jīng)常被使用灰粮,如HashMap仔涩。不可變保證了hashcode會(huì)一直相同,所以它可以緩存起來而不需要擔(dān)心改變粘舟。這也意味著熔脂,每次使用String的時(shí)候,不需要重新計(jì)算hashcode蓖乘,這使得性能更加有效锤悄,所以我們經(jīng)常會(huì)看到map的key使用字符串。
????3.線程安全
????????因?yàn)樽址遣豢勺兊募问悖允嵌嗑€程安全的零聚,同一個(gè)字符串實(shí)例可以被多個(gè)線程共享。這樣便不用因?yàn)榫€程安全問題而使用同步些侍。字符串自己便是線程安全的隶症。
例1:
StringBuffer和StringBuilder?:
????????當(dāng)對(duì)字符串進(jìn)行修改的時(shí)候,需要使用StringBuffer和StringBuilder類岗宣。和String類不同的是StringBuffer和 StringBuilder類的對(duì)象能夠被多次的修改蚂会,并且不產(chǎn)生新的未使用對(duì)象。
????????StringBuilder類在Java5中被提出耗式,它和StringBuffer之間的最大不同在于StringBuilder的方法不是線程安全的(不能同步訪問)胁住。
????????由于StringBuilder相較于StringBuffer有速度優(yōu)勢(shì),所以多數(shù)情況下建議使用StringBuilder類刊咳。然而在應(yīng)用程序要求線程安全的情況下彪见,則必須使用 StringBuffer 類。
????????Java StringBuffer 和 StringBuilder 類手冊(cè)
三者間的區(qū)別:
? ? ? ? 我們每次對(duì)String類型進(jìn)行改變的時(shí)候其實(shí)都等同于生成了一個(gè)新的 String 對(duì)象娱挨,然后將指針指向新的 String 對(duì)象余指,所以經(jīng)常改變內(nèi)容的字符串最好不要用 String ,因?yàn)槊看紊蓪?duì)象都會(huì)對(duì)系統(tǒng)性能產(chǎn)生影響跷坝,如下圖所示酵镜,這種情況下如果jvm中的GC(垃圾回收機(jī)制)沒有回收的話,內(nèi)存中已經(jīng)產(chǎn)生了一萬(wàn)多個(gè)對(duì)象
????????而如果是使用 StringBuffer 類則結(jié)果就不一樣了柴钻,每次結(jié)果都會(huì)對(duì) StringBuffer 對(duì)象本身進(jìn)行操作淮韭,而不是生成新的對(duì)象,再改變對(duì)象引用贴届。所以在一般情況下我們推薦使用 StringBuffer 靠粪,特別是字符串對(duì)象經(jīng)常改變的情況下
????????StringBuilder與StringBuffer?相比足丢,二者之間有公共父類AbstractStringBuilder(抽象類)。因此二者間很多方法都是公用的庇配,只是StringBuffer會(huì)在方法上加synchronized關(guān)鍵字,進(jìn)行同步绍些。因此通常來說應(yīng)該優(yōu)先使用 StringBuilder 類捞慌,因?yàn)樗С炙邢嗤牟僮鳎捎谒粓?zhí)行同步柬批,所以速度更快啸澡。但是如果將 StringBuilder 的實(shí)例用于多個(gè)線程是不安全的。需要這樣的同步氮帐,則建議使用 StringBuffer 嗅虏。
總結(jié):
????1.可變與不可變
? ??????String對(duì)象不可變 StringBuilder與StringBuffer可變
????2.是否多線程安全
? ??????String,StringBuffer線程安全上沐,StringBuilder線程不安全