亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

從源碼角度簡單看StringBuilder和StringBuffer的異同(全面解析)

2024-07-13 10:15:39
字體:
來源:轉載
供稿:網友

概述

StringBuilder和StringBuffer是兩個容易混淆的概念,本文從源碼入手,簡單看二者的異同。

容易知道的是,這兩者有一個是線程安全的,而且線程安全的那個效率低。

java doc里面的說明

java doc是寫源碼的人寫的注釋,先看java doc。

StringBuilder

A mutable sequence of characters. This class provides an API compatible with StringBuffer, but with no guarantee of synchronization. This class is designed for use as a drop-in replacement for StringBuffer in places where the string buffer was being used by a single thread (as is generally the case). Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations.

The principal operations on a StringBuilder are the append and insert methods, which are overloaded so as to accept data of any type. Each effectively converts a given datum to a string and then appends or inserts the characters of that string to the string builder. The append method always adds these characters at the end of the builder; the insert method adds the characters at a specified point.

For example, if z refers to a string builder object whose current contents are "start", then the method call z.append("le") would cause the string builder to contain "startle", whereas z.insert(4, "le") would alter the string builder to contain "starlet".

In general, if sb refers to an instance of a StringBuilder, then sb.append(x) has the same effect as sb.insert(sb.length(), x).

Every string builder has a capacity. As long as the length of the character sequence contained in the string builder does not exceed the capacity, it is not necessary to allocate a new internal buffer. If the internal buffer overflows, it is automatically made larger.

Instances of StringBuilder are not safe for use by multiple threads. If such synchronization is required then it is recommended that java.lang.StringBuffer be used.

Unless otherwise noted, passing a null argument to a constructor or method in this class will cause a NullPointerException to be thrown.

Since:
1.5
Author:
Michael McCloskey
See Also:
java.lang.StringBuffer
java.lang.String

StringBuffer

A thread-safe, mutable sequence of characters. A string buffer is like a String, but can be modified. At any point in time it contains some particular sequence of characters, but the length and content of the sequence can be changed through certain method calls.

String buffers are safe for use by multiple threads. The methods are synchronized where necessary so that all the operations on any particular instance behave as if they occur in some serial order that is consistent with the order of the method calls made by each of the individual threads involved.

The principal operations on a StringBuffer are the append and insert methods, which are overloaded so as to accept data of any type. Each effectively converts a given datum to a string and then appends or inserts the characters of that string to the string buffer. The append method always adds these characters at the end of the buffer; the insert method adds the characters at a specified point.

For example, if z refers to a string buffer object whose current contents are "start", then the method call z.append("le") would cause the string buffer to contain "startle", whereas z.insert(4, "le") would alter the string buffer to contain "starlet".

In general, if sb refers to an instance of a StringBuffer, then sb.append(x) has the same effect as sb.insert(sb.length(),

Whenever an operation occurs involving a source sequence (such as appending or inserting from a source sequence), this class synchronizes only on the string buffer performing the operation, not on the source. Note that while StringBuffer is designed to be safe to use concurrently from multiple threads, if the constructor or the append or insert operation is passed a source sequence that is shared across threads, the calling code must ensure that the operation has a consistent and unchanging view of the source sequence for the duration of the operation. This could be satisfied by the caller holding a lock during the operation's call, by using an immutable source sequence, or by not sharing the source sequence across threads.

Every string buffer has a capacity. As long as the length of the character sequence contained in the string buffer does not exceed the capacity, it is not necessary to allocate a new internal buffer array. If the internal buffer overflows, it is automatically made larger.

Unless otherwise noted, passing a null argument to a constructor or method in this class will cause a NullPointerException to be thrown.

As of release JDK 5, this class has been supplemented with an equivalent class designed for use by a single thread, StringBuilder. The StringBuilder class should generally be used in preference to this one, as it supports all of the same operations but it is faster, as it performs no synchronization.

Since:
JDK1.0
Author:
Arthur van Hoff
See Also:
java.lang.StringBuilder
java.lang.String

javadoc小結

從上面可以看出:

StringBuffer和StringBuilder都可以認為是可變的String。

StringBuffer是線程安全的,先出現,在JDK1.0的時候就有了。

StringBuilder是非線程安全的,后出現,在JDK1.5才有。

二者的接口完全一樣,StringBuilder更快。

其實,正常的用,知道這幾點就好了,不過還是想看看源碼里面怎么實現的。

源碼

如何實現線程安全

看源碼可以知道,這二者都繼承了一個抽象類AbstractStringBuilder

public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequencepublic final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence 

代碼量也不是很大,StringBuilder440行代碼,StringBuffer718行代碼,最多的是AbstractStringBuilder,一共1440行代碼。

看代碼從幾個角度看,一是一些關鍵的內部結構是怎么樣的,二是我們常用的函數是怎么實現的。因為String是不可變的,是放在常量池里面的。猜測StringBuilder和StringBuffer應該是用char數組實現的。

/** * The value is used for character storage. */ char[] value; /** * The count is the number of characters used. */ int count;

可以看出,用value存數據,用一個count表示長度。

看幾個常見方法的不同實現。

StringBuffer

 @Override public synchronized StringBuffer append(String str) { toStringCache = null; super.append(str); return this; } /** * @throws StringIndexOutOfBoundsException {@inheritDoc} */ @Override public synchronized StringBuffer insert(int offset, String str) { toStringCache = null; super.insert(offset, str); return this; } @Override public synchronized String toString() { if (toStringCache == null) {  toStringCache = Arrays.copyOfRange(value, 0, count); } return new String(toStringCache, true); }

StringBuilder

@Override public StringBuilder append(String str) { super.append(str); return this; } /** * @throws StringIndexOutOfBoundsException {@inheritDoc} */ @Override public StringBuilder insert(int offset, String str) { super.insert(offset, str); return this; }  @Override public String toString() { // Create a copy, don't share the array return new String(value, 0, count); }

由代碼可知,大部分情況想,StrinbBuffer只是增加了一個synchronized關鍵字來保證線程安全。但toString方法不同,這個后面再說。

初始化大小和如何增長

既然實際上是一個數組,那么數組開始的大小和增長的方法就很重要,我們通過代碼看一下。

/** * Constructs a string buffer with no characters in it and an * initial capacity of 16 characters. */ public StringBuffer() { super(16); } /** * Constructs a string builder with no characters in it and an * initial capacity of 16 characters. */ public StringBuilder() { super(16); }

可以看到,這兩個默認構造函數都說明默認的數組大小是16。

為什么是16呢?我沒想明白。

接下來關心如何增長的?我們看看append的實現

public AbstractStringBuilder append(String str) { if (str == null)  return appendNull(); int len = str.length(); ensureCapacityInternal(count + len); str.getChars(0, len, value, count); count += len; return this; } /** * This method has the same contract as ensureCapacity, but is * never synchronized. */ private void ensureCapacityInternal(int minimumCapacity) { // overflow-conscious code if (minimumCapacity - value.length > 0)  expandCapacity(minimumCapacity); }  /** * This implements the expansion semantics of ensureCapacity with no * size check or synchronization. */ void expandCapacity(int minimumCapacity) { int newCapacity = value.length * 2 + 2; if (newCapacity - minimumCapacity < 0)  newCapacity = minimumCapacity; if (newCapacity < 0) {  if (minimumCapacity < 0) // overflow  throw new OutOfMemoryError();  newCapacity = Integer.MAX_VALUE; } value = Arrays.copyOf(value, newCapacity); }

上面三個方法說明了如何擴容。

把當前的容量*2+2

如果新增加的長度大于這個值,則設為新增加的值

如果溢出,則拋出OutOfMemoryError

StringBuffer中toString的實現

/** * A cache of the last value returned by toString. Cleared * whenever the StringBuffer is modified. */ private transient char[] toStringCache; @Override public synchronized StringBuffer append(String str) { toStringCache = null; super.append(str); return this; } @Override public synchronized String toString() { if (toStringCache == null) {  toStringCache = Arrays.copyOfRange(value, 0, count); } return new String(toStringCache, true); }

可以看到,定義了一個數組toStringCache,每次數據有變化,都把這個設置為null。在toString的時候,再重新從當前數據里面拿。

transient關鍵字是為了避免這個數組被序列化。

小結

其實java本身的源碼寫的還是比較簡單的,學習知識如果能從源碼入手,能夠更深入的理解很多原理。本文只是簡單的列舉了一部分源碼,簡單說明StringBuffer和StringBuilder的異同。有興趣的朋友可以自己看一下。

以上這篇從源碼角度簡單看StringBuilder和StringBuffer的異同(全面解析)就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久视频在线播放| 欧美疯狂性受xxxxx另类| 国产成人精品日本亚洲| 久久久这里只有精品视频| 欧美性猛交xxxx免费看漫画| 在线观看精品自拍私拍| 97色在线视频| 成人羞羞国产免费| 欧美成人合集magnet| 亚洲精品国产精品国自产观看浪潮| 成人国产精品一区| 日本成熟性欧美| 亚洲一区二区自拍| 久久资源免费视频| 欧美日韩亚洲视频一区| 欧美日韩一区免费| 91精品视频网站| 亚洲精品久久久久久久久久久久| 操日韩av在线电影| 国产一区二区三区在线观看视频| 国产精品久久久久福利| 国产日产久久高清欧美一区| 日韩精品久久久久久福利| 日韩中文字幕欧美| 欧美一级淫片aaaaaaa视频| 国产欧美一区二区三区在线| 日韩精品极品在线观看播放免费视频| 日韩在线观看免费| 久久免费视频网站| xxxxxxxxx欧美| 国产日本欧美一区二区三区| 国内免费久久久久久久久久久| 国内精品久久久久久中文字幕| 美女黄色丝袜一区| 91网在线免费观看| 在线精品播放av| 国产精品久久久久久久午夜| 国产性猛交xxxx免费看久久| 欧美日韩成人网| 色视频www在线播放国产成人| 日本中文字幕不卡免费| 高清欧美性猛交| www.国产精品一二区| 色偷偷偷综合中文字幕;dd| 国产精品主播视频| 91产国在线观看动作片喷水| 欧洲成人性视频| 欧美一级视频在线观看| 国产精品成人观看视频国产奇米| 亚洲久久久久久久久久| 成人a级免费视频| 国产精品美女久久| 国产精品福利网| 亚洲电影成人av99爱色| 国产97人人超碰caoprom| 日韩亚洲欧美中文高清在线| 久久久久久亚洲精品不卡| 26uuu另类亚洲欧美日本老年| 国产成人avxxxxx在线看| 精品久久久久久久久国产字幕| 亚洲最大的av网站| 亚洲图中文字幕| 国产在线精品成人一区二区三区| 久久在精品线影院精品国产| 精品成人久久av| 日韩精品免费在线观看| 欧洲日韩成人av| 亚洲国产精品久久久| 亚洲成人网在线观看| wwwwwwww亚洲| 国产精品91一区| 91免费视频网站| 亚洲精品国产综合区久久久久久久| 久久成人精品电影| 亚洲欧美另类国产| 国语自产精品视频在线看一大j8| 久久久久国产精品www| 国产成人精品电影久久久| 久久精品国亚洲| 欧美极品少妇xxxxⅹ裸体艺术| 91av免费观看91av精品在线| 裸体女人亚洲精品一区| 日本一欧美一欧美一亚洲视频| 国产精品香蕉国产| 亚洲欧美综合v| 亚洲一区二区三区乱码aⅴ| 亚洲国产精品成人一区二区| 亚洲国产精品成人va在线观看| 国产成人精品久久二区二区| 欧美日韩中文字幕在线| 国产精品jvid在线观看蜜臀| 人人澡人人澡人人看欧美| 久久久精品国产一区二区| 成人激情视频小说免费下载| 91理论片午午论夜理片久久| 91成人在线播放| 国产精品一区专区欧美日韩| 国产视频久久久久久久| 欧美激情精品久久久久久大尺度| 尤物yw午夜国产精品视频明星| 久热精品视频在线免费观看| 久久色免费在线视频| 亚洲精品久久在线| 日韩在线观看网址| 亚洲欧美国产va在线影院| 国产一区二区三区在线播放免费观看| 97碰在线观看| 欧美日韩亚洲激情| 亚洲美女免费精品视频在线观看| 国产精品看片资源| www.日韩欧美| 久久久免费精品视频| 亚洲精品福利在线观看| 日韩美女av在线免费观看| 国产999精品久久久影片官网| 国产成人久久精品| 国产精品一区二区女厕厕| 日韩精品一二三四区| 91亚洲人电影| 国产一区二区三区在线观看网站| 国产区精品视频| 国产精品久久久久久久久久久新郎| 国产精品极品尤物在线观看| 欧美老女人性生活| 国产精品久久久久久久久久小说| 欧洲亚洲免费视频| 成人黄色网免费| 欧美富婆性猛交| 亚洲精品午夜精品| 成人黄色免费片| 91精品国产综合久久香蕉的用户体验| 欧美韩国理论所午夜片917电影| 91国偷自产一区二区三区的观看方式| 视频在线观看99| 欧美福利视频在线观看| 亚洲电影在线观看| 欧美小视频在线| 成人av色在线观看| 亚州欧美日韩中文视频| 欧美一性一乱一交一视频| 日韩av黄色在线观看| 欧美限制级电影在线观看| 色婷婷av一区二区三区久久| 少妇高潮 亚洲精品| 中文字幕视频一区二区在线有码| 中文国产亚洲喷潮| 欧美专区第一页| www.xxxx精品| 国产精品入口免费视频一| 一本色道久久综合亚洲精品小说| 揄拍成人国产精品视频| 精品福利在线视频| 日韩高清欧美高清| 亚洲精品久久久久久久久久久久久| 日韩成人av在线播放| 日韩精品有码在线观看| 国产精品久久久久久久9999| 成人性生交大片免费观看嘿嘿视频| 国产精品h片在线播放| 欧美性黄网官网| 日韩高清电影好看的电视剧电影| 欧美日韩久久久久| 亚洲男人7777| 国产精品视频精品|