欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java那點(diǎn)事——StringBuffer與StringBuilder原理與區(qū)別

 更新時(shí)間:2016年06月14日 10:30:34   作者:jmatrix  
本文給大家分享StringBuffer與StringBuilder的區(qū)別,它們的應(yīng)用場(chǎng)景是什么?非常不錯(cuò),面試考官經(jīng)??嫉囊粋€(gè)問(wèn)題,有需要的朋友跟著腳本之家小編一起學(xué)習(xí)吧

最近在找工作,考官問(wèn)我一個(gè)簡(jiǎn)單的題目:“StringBuffer與StringBuilder的區(qū)別,它們的應(yīng)用場(chǎng)景是什么?”,下面小編答案分享給大家,方便以后大家學(xué)習(xí),以此也做個(gè)備錄。

其實(shí)只要找下Google大神就有答案了:StringBuffer 與 StringBuilder 中的方法和功能完全是等價(jià)的,只是StringBuffer 中的方法大都采用了 synchronized 關(guān)鍵字進(jìn)行修飾,因此是線程安全的,而 StringBuilder 沒(méi)有這個(gè)修飾,可以被認(rèn)為是線程不安全的。

為了更好的理解上述的答案,還是直接看StringBuffer與StringBuilder的源碼實(shí)現(xiàn)比較實(shí)在,作為一個(gè)程序猿,“有疑問(wèn),看源碼”才是正道,我可以負(fù)責(zé)任的說(shuō),當(dāng)然了得有條件才行!

jdk的實(shí)現(xiàn)中StringBuffer與StringBuilder都繼承自AbstractStringBuilder,對(duì)于多線程的安全與非安全看到StringBuffer中方法前面的一堆synchronized就大概了解了。

這里隨便講講AbstractStringBuilder的實(shí)現(xiàn)原理:我們知道使用StringBuffer等無(wú)非就是為了提高java中字符串連接的效率,因?yàn)橹苯邮褂?進(jìn)行字符串連接的話,jvm會(huì)創(chuàng)建多個(gè)String對(duì)象,因此造成一定的開(kāi)銷。AbstractStringBuilder中采用一個(gè)char數(shù)組來(lái)保存需要append的字符串,char數(shù)組有一個(gè)初始大小,當(dāng)append的字符串長(zhǎng)度超過(guò)當(dāng)前char數(shù)組容量時(shí),則對(duì)char數(shù)組進(jìn)行動(dòng)態(tài)擴(kuò)展,也即重新申請(qǐng)一段更大的內(nèi)存空間,然后將當(dāng)前char數(shù)組拷貝到新的位置,因?yàn)橹匦路峙鋬?nèi)存并拷貝的開(kāi)銷比較大,所以每次重新申請(qǐng)內(nèi)存空間都是采用申請(qǐng)大于當(dāng)前需要的內(nèi)存空間的方式,這里是2倍。

接下來(lái),玩些好玩的!

在Google中出來(lái)了這么一些信息:


StringBuffer 始于 JDK 1.0
StringBuilder 始于 JDK 1.5

從 JDK 1.5 開(kāi)始,帶有字符串變量的連接操作(+),JVM 內(nèi)部采用的是
StringBuilder 來(lái)實(shí)現(xiàn)的,而之前這個(gè)操作是采用 StringBuffer 實(shí)現(xiàn)的。

我們通過(guò)一個(gè)簡(jiǎn)單的程序來(lái)看其執(zhí)行的流程:

清單1 Buffer.java

public class Buffer { 
public static void main(String[] args) { 
String s1 = "aaaaa"; 
String s2 = "bbbbb"; 
String r = null; 
int i = 3694; 
r = s1 + i + s2; 

for(int j=0;i<10;j++){ 
r+="23124"; 
} 
} 
} 

使用命令javap -c Buffer查看其字節(jié)碼實(shí)現(xiàn):

清單2 Buffer類字節(jié)碼

將清單1和清單2對(duì)應(yīng)起來(lái)看,清單2的字節(jié)碼中l(wèi)dc指令即從常量池中加載“aaaaa”字符串到棧頂,istore_1將“aaaaa”存到變量1中,后面的一樣,sipush是將一個(gè)短整型常量值(-32768~32767)推送至棧頂,這里是常量“3694”,更多的Java指令集請(qǐng)查看另一篇文章“Java指令集”。

讓我們直接看到13,13~17是new了一個(gè)StringBuffer對(duì)象并調(diào)用其初始化方法,20~21則是先通過(guò)aload_1將變量1壓到棧頂,前面說(shuō)過(guò)變量1放的就是字符串常量“aaaaa”,接著通過(guò)指令invokevirtual調(diào)用StringBuffer的append方法將“aaaaa”拼接起來(lái),后續(xù)的24~30同理。最后在33調(diào)用StringBuffer的toString函數(shù)獲得String結(jié)果并通過(guò)astore存到變量3中。

看到這里可能有人會(huì)說(shuō),“既然JVM內(nèi)部采用了StringBuffer來(lái)連接字符串了,那么我們自己就不用用StringBuffer,直接用”+“就行了吧!“。是么?當(dāng)然不是了。俗話說(shuō)”存在既有它的理由”,讓我們繼續(xù)看后面的循環(huán)對(duì)應(yīng)的字節(jié)碼。

37~42都是進(jìn)入for循環(huán)前的一些準(zhǔn)備工作,37,38是將j置為1。44這里通過(guò)if_icmpge將j與10進(jìn)行比較,如果j大于10則直接跳轉(zhuǎn)到73,也即return語(yǔ)句退出函數(shù);否則進(jìn)入循環(huán),也即47~66的字節(jié)碼。這里我們只需看47到51就知道為什么我們要在代碼中自己使用StringBuffer來(lái)處理字符串的連接了,因?yàn)槊看螆?zhí)行“+”操作時(shí)jvm都要new一個(gè)StringBuffer對(duì)象來(lái)處理字符串的連接,這在涉及很多的字符串連接操作時(shí)開(kāi)銷會(huì)很大。

相關(guān)文章

  • JavaEE SpringMyBatis是什么? 它和Hibernate的區(qū)別及如何配置MyBatis

    JavaEE SpringMyBatis是什么? 它和Hibernate的區(qū)別及如何配置MyBatis

    這篇文章主要介紹了JavaEE Spring MyBatis是什么? 它和Hibernate的區(qū)別有哪些?如何配置MyBatis?本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • struts升級(jí)到2.5.2遇到的問(wèn)題及解決方案(推薦)

    struts升級(jí)到2.5.2遇到的問(wèn)題及解決方案(推薦)

    原來(lái)的版本是2.3.x,由于安全原因需要升級(jí)到2.5.2。但是在升級(jí)過(guò)程中遇到各種各樣的問(wèn)題,下面小編給大家?guī)?lái)了struts升級(jí)到2.5.2遇到的問(wèn)題及解決方案,需要的朋友參考下吧
    2016-11-11
  • Java并發(fā)工具類之CountDownLatch詳解

    Java并發(fā)工具類之CountDownLatch詳解

    這篇文章主要介紹了Java并發(fā)工具類之CountDownLatch詳解,CountDownLatch可以使一個(gè)獲多個(gè)線程等待其他線程各自執(zhí)行完畢后再執(zhí)行,CountDownLatch可以解決那些一個(gè)或者多個(gè)線程在執(zhí)行之前必須依賴于某些必要的前提業(yè)務(wù)先執(zhí)行的場(chǎng)景,需要的朋友可以參考下
    2023-12-12
  • mybatis實(shí)現(xiàn)查詢操作及獲得添加的ID

    mybatis實(shí)現(xiàn)查詢操作及獲得添加的ID

    這篇文章主要介紹了mybatis實(shí)現(xiàn)查詢操作及獲得添加的ID,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-11-11
  • 詳解SpringMVC中設(shè)置靜態(tài)資源不被攔截的問(wèn)題

    詳解SpringMVC中設(shè)置靜態(tài)資源不被攔截的問(wèn)題

    這篇文章主要介紹了詳解SpringMVC中設(shè)置靜態(tài)資源不被攔截的問(wèn)題,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-02-02
  • SpringBoot使用JWT實(shí)現(xiàn)登錄驗(yàn)證的方法示例

    SpringBoot使用JWT實(shí)現(xiàn)登錄驗(yàn)證的方法示例

    這篇文章主要介紹了SpringBoot使用JWT實(shí)現(xiàn)登錄驗(yàn)證的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • java ThreadLocal?類常用方法源碼解析

    java ThreadLocal?類常用方法源碼解析

    這篇文章主要為大家介紹了java ThreadLocal類常用方法源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • 完美解決java.lang.OutOfMemoryError處理錯(cuò)誤的問(wèn)題

    完美解決java.lang.OutOfMemoryError處理錯(cuò)誤的問(wèn)題

    下面小編就為大家?guī)?lái)一篇完美解決java.lang.OutOfMemoryError處理錯(cuò)誤的問(wèn)題。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-01-01
  • Java?通過(guò)手寫分布式雪花SnowFlake生成ID方法詳解

    Java?通過(guò)手寫分布式雪花SnowFlake生成ID方法詳解

    SnowFlake是twitter公司內(nèi)部分布式項(xiàng)目采用的ID生成算法,開(kāi)源后廣受國(guó)內(nèi)大廠的好評(píng)。由這種算法生成的ID,我們就叫做SnowFlakeID,下面我們來(lái)詳細(xì)看看
    2022-04-04
  • SpringBoot進(jìn)行Web開(kāi)發(fā)的實(shí)現(xiàn)

    SpringBoot進(jìn)行Web開(kāi)發(fā)的實(shí)現(xiàn)

    Spring?Boot讓我們可以快速構(gòu)建項(xiàng)目并運(yùn)行web應(yīng)用,大大簡(jiǎn)化了Spring的復(fù)雜配置,本文主要介紹了SpringBoot進(jìn)行Web開(kāi)發(fā)的實(shí)現(xiàn),感興趣的可以了解一下
    2023-10-10

最新評(píng)論