1、源码片段
String源码片段:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/ **该值用于字符存储。* /
private final char value[];
/ **缓存字符串的哈希码* /
private int hash; // Default to 0
/ **使用来自jdk 1.0.2的串行版本uid来实现互操作性* /
private static final long serialVersionUID = -6849794470754667710L;
/ **类字符串在序列化流协议内是特殊情况。 * *根据* *对象序列化规范,第6.2节“流”,将字符串实例写入对象输出流元素” * /
private static final ObjectStreamField[] serialPersistentFields =
new ObjectStreamField[0];
/ **初始化一个新创建的{@code string}对象,以便它表示一个空字符序列。注意,由于字符串是不可变的,因此不需要使用此构造函数。 * /
public String() {
this.value = "".value;
}
/ **初始化一个新创建的{@code string}对象,以便它表示*与参数相同的字符序列;换句话说,*新创建的字符串是参数字符串的副本。除非需要{@code original}的显式副本,否则不需要使用此构造函数,因为字符串是不可变的。 * * @param原始*一个{@code字符串} * /
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
/ **分配一个新的{@code string},以便它表示字符数组参数中当前包含的*个字符的序列。 *复制字符数组的内容; *字符数组的后续修改不会影响新创建的字符串。 * * @参数值*字符串的初始值* /
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
}
StringBuild源码片段:
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
static final long serialVersionUID = 4383685877147921099L;
public StringBuilder() {
super(16);
}
public StringBuilder(int capacity) {
super(capacity);
}
public StringBuilder(String str) {
super(str.length() + 16);
append(str);
}
public StringBuilder(CharSequence seq) {
this(seq.length() + 16);
append(seq);
}
}
StringBuffer源码片段:
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
private transient char[] toStringCache;
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);
}
}
AbstractStringBuilder源码片段:
abstract class AbstractStringBuilder implements Appendable, CharSequence {
char[] value;
int count;
AbstractStringBuilder() {
}
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
/ **扩容方法 * /
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);
}
}
由源码可见String中定义的用于存储的char[] 数组使用了final字段来进行修饰,属于不可变字符序列,而StringBuild和StringBuffer的均是调用父类AbstractStringBuilder的构造方法创建的,而AbstractStringBuilder定义的char[]数组没有final修饰,属于可变数组,因此StringBuild和StringBuffer属于可变字符序列。
2、三者在字符修改上的区别
类别 | 是否可变 | 执行效率 | 是否线程安全 |
String | 否 | 低 | char[]数组使用final修饰,线程安全 |
StringBuild | 是 | 高 | 线程不安全 |
StringBuffer | 是 | 较高 | append()方法加有synchronized,线程安全 |
参考博客:
https://blog.csdn.net/weixin_41101173/article/details/79677982