您的位置:首页 > 产品设计 > UI/UE

【Java】String、StringBuilder与StringBuffer

2016-09-28 11:59 429 查看
String 字符串常量

StringBuilder 字符串变量(字符数组),非线程安全

StringBuffer 字符串变量(字符数组),线程安全

String

不可变常量

private final char value[];


String中的字符数组
value[]
定义为
final
,所以String是不可变的。

线程安全

String是不可变的,字符串常量,所以String是线程安全的。

拼接

加号拼接

Java没有运算符重载,编译的时候检测到
+
号拼接字符串,则编译器将用StringBuilder代替。

String str1 = "a";


String str2 = "b";


String str3 = "c";


String str = str1 + str2 + str3;


编译器则会转换成(避免了多次创建String对象作为中间量,但是用完就直接变成垃圾了)

String str = new StringBuilder(str1).append(str2).append(str3);


还有一种情况:

String str = "a" + "b" + "c";


编译器则直接转换成

String str = "abc";


concat()方法

在字符串的尾部拼接指定的字符串。

public String concat(String str) {
int otherLen = str.length();

//如果指定字符串长度为0,则直接返回字符串本身。
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
//将str copy到buf[]字符数组后,并由buf[]创建新的String对象返回
str.getChars(buf, len);
return new String(buf, true);
}

void getChars(char dst[], int dstBegin) {
System.arraycopy(value, 0, dst, dstBegin, value.length);
}

public static native void arraycopy(Object src,  int  srcPos,
Object dest, int destPos,
int length);


StringBuffer

可变字符串

char[] value;


可指定字符数组长度

public StringBuffer(int capacity) {
super(capacity);
}

//初始长度为16
public StringBuffer() {
super(16);
}
public StringBuffer(String str) {
super(str.length() + 16);
append(str);
}


线程安全

线程安全,方法都用关键字
synchronized
修饰。

toStringCache

private transient char[] toStringCache;


在任何修改字符串的方法执行前,都将该变量设为null。当调用toString()方法时,返回该缓存,如果该缓存为空,则将
value
copy到该数组中。toString()方法返回的是这个数组创建的字符串。StringBuilder没有这个变量,这样子设计,可能是因为 StringBuilder 一般不会在多线程环境中使用,所以不太可能出现连接多次调用 StringBuilder.toString(),因此没有必要共享。

StringBuilder

可变字符串

char[] value;


可指定字符数组长度

跟StringBuffer一致

线程不安全

是轻量级StringBuffer,没有实现线程同步,效率更高,因为锁的获取和释放会带来开销。

问题 mark

public StringBuffer insert(int dstOffset, CharSequence s)


StringBuffer中没有加锁,而且也没有请toStringCache,还没搞懂。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息