一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - Java那點事——StringBuffer與StringBuilder原理與區別

Java那點事——StringBuffer與StringBuilder原理與區別

2020-05-15 11:03jmatrix JAVA教程

本文給大家分享StringBuffer與StringBuilder的區別,它們的應用場景是什么?非常不錯,面試考官經常考的一個問題,有需要的朋友跟著腳本之家小編一起學習吧

最近在找工作,考官問我一個簡單的題目:“StringBufferStringBuilder的區別,它們的應用場景是什么?”,下面小編答案分享給大家,方便以后大家學習,以此也做個備錄。

其實只要找下Google大神就有答案了:StringBuffer 與 StringBuilder 中的方法和功能完全是等價的,只是StringBuffer 中的方法大都采用了 synchronized 關鍵字進行修飾,因此是線程安全的,而 StringBuilder 沒有這個修飾,可以被認為是線程不安全的。

為了更好的理解上述的答案,還是直接看StringBuffer與StringBuilder的源碼實現比較實在,作為一個程序猿,“有疑問,看源碼”才是正道,我可以負責任的說,當然了得有條件才行!

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

這里隨便講講AbstractStringBuilder的實現原理:我們知道使用StringBuffer等無非就是為了提高java中字符串連接的效率,因為直接使用+進行字符串連接的話,jvm會創建多個String對象,因此造成一定的開銷。AbstractStringBuilder中采用一個char數組來保存需要append的字符串,char數組有一個初始大小,當append的字符串長度超過當前char數組容量時,則對char數組進行動態擴展,也即重新申請一段更大的內存空間,然后將當前char數組拷貝到新的位置,因為重新分配內存并拷貝的開銷比較大,所以每次重新申請內存空間都是采用申請大于當前需要的內存空間的方式,這里是2倍。

接下來,玩些好玩的!

在Google中出來了這么一些信息:


StringBuffer 始于 JDK 1.0
StringBuilder 始于 JDK 1.5

從 JDK 1.5 開始,帶有字符串變量的連接操作(+),JVM 內部采用的是
StringBuilder 來實現的,而之前這個操作是采用 StringBuffer 實現的。

我們通過一個簡單的程序來看其執行的流程:

清單1 Buffer.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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查看其字節碼實現:

Java那點事——StringBuffer與StringBuilder原理與區別

清單2 Buffer類字節碼

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

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

看到這里可能有人會說,“既然JVM內部采用了StringBuffer來連接字符串了,那么我們自己就不用用StringBuffer,直接用”+“就行了吧!“。是么?當然不是了。俗話說”存在既有它的理由”,讓我們繼續看后面的循環對應的字節碼。

37~42都是進入for循環前的一些準備工作,37,38是將j置為1。44這里通過if_icmpge將j與10進行比較,如果j大于10則直接跳轉到73,也即return語句退出函數;否則進入循環,也即47~66的字節碼。這里我們只需看47到51就知道為什么我們要在代碼中自己使用StringBuffer來處理字符串的連接了,因為每次執行“+”操作時jvm都要new一個StringBuffer對象來處理字符串的連接,這在涉及很多的字符串連接操作時開銷會很大。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 色哟哟国产成人精品 | 91大神大战高跟丝袜美女 | 四虎884aa永久播放地址http | 色综合久久六月婷婷中文字幕 | 国产欧美日韩在线播放 | 无码人妻视频又大又粗欧美 | 国产91青青成人a在线 | 日本高清二三四本2021 | 国产欧美日韩视频在线观看一区二区 | 欧美性另类69xxxx | 免费观看二十女人一摸是水 | 青青成人在线 | 国内精品久久久久久久 | 小草视频免费观看在线 | 国产激情久久久久影院小草 | 四虎永久免费在线观看 | 亚洲 欧美 日本 国产 高清 | 精品欧美男同同性videos | 无遮免费网站在线入口 | 婷婷丁香视频 | 国内精品91东航翘臀女神在线 | 日韩免费在线视频观看 | 精品久久成人免费第三区 | 无人区在线观看免费国语完整版 | 亚洲国产视频网站 | 亚洲免费在线观看视频 | 男女小视频在线观看 | 色综合天天综合网站中国 | 97伊人久久精品亚洲午夜 | 无限在线观看免费入口 | 先锋资源av | 精品国产中文字幕在线视频 | 成人一区二区丝袜美腿 | 99精品影视| 423hk四虎 | 高h短篇校园1v1 | 四虎影视在线观看永久地址 | 日本黄色大片网站 | 午夜a一级毛片 | 免费视频专区一国产盗摄 | 久久艹综合 |