我们在开发的时候,在处理字段的时候遇到大量的字符拼接的时候会使用StringBuffer和StringBuild。这是为什么呢?那就是因为String会在每一次创建的时候都会新建一个对象,原来的对象也不会被删除,还有就是说还有StringBuffer和StringBuild有什么区别呢?带着这个疑问我们看一下源码
//从类上看,他使用了final关键字,说明这个类是不可以改变的,且继承了Serializable,他是可以被序列化的
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
//还有这个存储我们的字符串的value 也是被final 修饰了所以他这个值是不可以改变的
private final char value[];
javac Test 编译文件
javap -c Test 查看虚拟机指令
实验一:纯字符串
public class Test {
public static void main(String args[]) {
String str = "a";
}
}
// 将字符串 a 存入常数池
0: ldc #2; //String a
// 将引用存放到 1 号局部变量中
2: astore_1
3: return
实验二:纯字符串相加
public class Test {
public static void main(String args[]) {
String str = "a" + "b";
}
}
// 将字符串 ab 压入常数池
0: ldc #2; //String ab
2: astore_1
3: return
实验二能够非常明显地看出,编译器在编译时产生的字节码已经将 "a" + "b" 优化成了 "ab",
同理多个字符串的相加也会被优化处理,须要注意的是字符串常量相加。
实验三:字符串与自己主动提升常量相加
public class Test {
public static void main(String args[]) {
String str = "a" + (1 + 2);
}
}
// 将字符串 a3 压入常数池
0: ldc #2; //String a3
2: astore_1
3: return
通过虚拟机指令能够看出,1 + 2 自己主动提升后的常量与字符串常量,虚拟机也会对其进行优化。
String b = new StringBuilder().append("a").append(bb).toString();
// 看到这个类也是不能被继承的且继承了AbstractStringBuilder的抽象类
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
………………
}
在这里我们可以看到他是使用了锁的。
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
// 看到这个类我们也可以看到他也继承了AbstractStringBuilder
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
/** use serialVersionUID for interoperability */
static final long serialVersionUID = 4383685877147921099L;
/**
* Constructs a string builder with no characters in it and an
* initial capacity of 16 characters.
*/
public StringBuilder() {
super(16);
}
// 这也可以看看,他这块是没有使用Sychronized这把锁的
@Override
public StringBuilder append(String str) {
// 这就是重点他也是使用了AbstractStringBuilder中的apend方法。
super.append(str);
return this;
}
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;
}
https://www.cnblogs.com/chenlong-50954265/p/5632275.html https://blog.csdn.net/weixin_33713707/article/details/85912589