[源码]String StringBuffer StringBudliderStringBuffer StringBuilder源码分析
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[源码]String StringBuffer StringBudliderStringBuffer StringBuilder源码分析相关的知识,希望对你有一定的参考价值。
纵骑横飞 章仕烜
昨天比较忙 今天把StringBuffer StringBulider的源码分析 献上
在讲 StringBuffer StringBuilder 之前 ,我们先看一下 它们共同的老祖宗
AbstractStringBuilder
![技术分享](https://image.cha138.com/20210825/d871b78e0a0e4deea12d0906e9153a83.jpg)
这是 StringBuilder StringBuffer 的根基
再看看 这两个实现类 里边有什么
![技术分享](https://image.cha138.com/20210825/4d225bf49d04417687593f617c6aa73c.jpg)
![技术分享](https://image.cha138.com/20210825/81d12d2f20d44ca3930946b697a5d11c.jpg)
很显然,这两个东西什么都没写吧
我们看看 另一个门派的 String
![技术分享](https://image.cha138.com/20210825/2d7d3fe03aa04b3ab7c4f38567d30b19.jpg)
看出 为什么 我们说String 对象是不可变的 StringBuilder StringBuffer 可变的原因了吗?
就是 上面 的 三个final 对吧
好 那么我们都知道了 String 是不可变的 ,也就是说 就像 一次性纸杯,你如果想要50ml
那就拿50ml的杯子 想100ml 就拿 100ml的杯子 不需要换杯子
然后就是 一个问题: StringBuffer StringBuilder 底层是一堆数组 它们是如何扩容的?
所谓 容量 就是 底层数组的实际长度 ,比如说 ArrayList 底层当然是个array
这个集合 里边加的东西 不是不限个嘛 怎么做到这种效果 ,用的就是 CAPACITY
大家需要知道 扩容的3个问题:
1. 默认 容量是多少?
2. 如何扩容 ?
3. 和 length 是什么区别 ?
再有一个问题 StringBuffer 为什么是线程安全的?
这是简略版 的 StringBuffer 大家可以看一下
public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence { static final long serialVersionUID = 3388685877147921107L; public StringBuffer() { super(16); } public StringBuffer(int capacity) { super(capacity); } public StringBuffer(String str) { super(str.length() + 16); append(str); } /** *这边也是一样的 */ public StringBuffer(CharSequence seq) { this(seq.length() + 16); append(seq); } public synchronized int length() { return count; } public synchronized int capacity() { return value.length; } /** * jdk 直接对外提供的 扩容 方法 */ public synchronized void ensureCapacity(int minimumCapacity) { if (minimumCapacity > value.length) { expandCapacity(minimumCapacity); } } /** * trim to actual size 也就是 array.length ---> count */ public synchronized void trimToSize() { super.trimToSize(); }public synchronized void setLength(int newLength) { super.setLength(newLength); } public synchronized char charAt(int index) { if ((index < 0) || (index >= count)) throw new StringIndexOutOfBoundsException(index); return value[index]; } public synchronized int codePointAt(int index) { return super.codePointAt(index); } public synchronized int codePointBefore(int index) { return super.codePointBefore(index); } public synchronized int codePointCount(int beginIndex, int endIndex) { return super.codePointCount(beginIndex, endIndex); } public synchronized int offsetByCodePoints(int index, int codePointOffset) { return super.offsetByCodePoints(index, codePointOffset); } public synchronized void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) { super.getChars(srcBegin, srcEnd, dst, dstBegin); } public synchronized void setCharAt(int index, char ch) { if ((index < 0) || (index >= count)) throw new StringIndexOutOfBoundsException(index); value[index] = ch; } /** * append */ public synchronized StringBuffer append(Object obj) { super.append(String.valueOf(obj)); return this; } public synchronized StringBuffer appendCodePoint(int codePoint) { super.appendCodePoint(codePoint); return this; } public synchronized StringBuffer delete(int start, int end) { super.delete(start, end); return this; } public synchronized StringBuffer replace(int start, int end, String str) { super.replace(start, end, str); return this; } public synchronized CharSequence subSequence(int start, int end) { return super.substring(start, end); } public synchronized String substring(int start, int end) { return super.substring(start, end); } public synchronized StringBuffer insert(int index, char str[], int offset, int len) { super.insert(index, str, offset, len); return this; } public synchronized StringBuffer insert(int offset, String str) { super.insert(offset, str); return this; } public synchronized StringBuffer insert(int offset, char str[]) { super.insert(offset, str); return this; } public synchronized StringBuffer insert(int dstOffset, CharSequence s, int start, int end) { super.insert(dstOffset, s, start, end); return this; } /** * 默认检索起始位置 为 0 */ public int indexOf(String str) { return indexOf(str, 0); } public synchronized int indexOf(String str, int fromIndex) { return String.indexOf(value, 0, count, str.toCharArray(), 0, str.length(), fromIndex); } public int lastIndexOf(String str) { // Note, synchronization achieved via other invocations return lastIndexOf(str, count); } public synchronized int lastIndexOf(String str, int fromIndex) { return String.lastIndexOf(value, 0, count, str.toCharArray(), 0, str.length(), fromIndex); } /** * reverse 和 replace 这些和 顺序 有关的方法 * 在 Collections 里边也有 只不过 只支持 List 实现类(与顺序相关) */ public synchronized StringBuffer reverse() { super.reverse(); return this; } public synchronized String toString() { return new String(value, 0, count); } private static final java.io.ObjectStreamField[] serialPersistentFields = { new java.io.ObjectStreamField("value", char[].class), new java.io.ObjectStreamField("count", Integer.TYPE), new java.io.ObjectStreamField("shared", Boolean.TYPE), }; private synchronized void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { java.io.ObjectOutputStream.PutField fields = s.putFields(); fields.put("value", value); fields.put("count", count); fields.put("shared", false); s.writeFields(); } private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { java.io.ObjectInputStream.GetField fields = s.readFields(); value = (char[])fields.get("value", null); count = (int)fields.get("count", 0); } }
StringBuilder 相对于 StringBuffer 就是没有 加锁
以上是关于[源码]String StringBuffer StringBudliderStringBuffer StringBuilder源码分析的主要内容,如果未能解决你的问题,请参考以下文章
String-StringBuffer-StringBuilder的区别和源码分析
STRING-STRINGBUFFER-STRINGBUILDER的区别和源码分析
[源码]String StringBuffer StringBudlider(1String部分)
我的jdk源码:StringBuffer 线程安全可多次修改String
[源码]String StringBuffer StringBudliderStringBuffer StringBuilder源码分析