文章目录
String
不可变类, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,这样不仅效率低下,而且大量浪费有限的内存空间,所以经常改变内容的字符串最好不要用 String 。
举例:
public static void main(String[] args){
String s1 = "a";
String s2 = "b";
String s3 = "ab";
String s4 = s1 + s2;
System.out.println(s3==s4); // false
return;
}
原因是:String s4 = s1 + s2; 其底层是:
new StringBuilder().append("a").append("b").toString();
toString==》new String(“ab”);在堆里面
而s1,s2,s3都在常量池,所以不一样
如果是
String s5 = "a" + "b";
System.out.println(s3==s5); //true
原因是,s5是由两个确定的值相加构成,s5的值就是确定的,javac在编译期间的优化,结果已经在编译器确定为ab,所以相等。
StringBuffer 和 StringBuilder 类
可变类
当对字符串进行修改的时候,特别是字符串对象经常改变的情况下,需要使用 StringBuffer 和 StringBuilder 类。
StringBuffer 字符串变量(线程安全)
StringBuilder 字符串变量(非线程安全)
列出一部分源码,就能看出在源代码中StringBuffer的很多方法都被关键字synchronized 修饰了,而StringBuilder没有。
StringBuilder源码
@Override
public StringBuilder append(char[] str, int offset, int len) {
super.append(str, offset, len);
return this;
}
@Override
public StringBuilder append(boolean b) {
super.append(b);
return this;
}
StringBuffer源码
@Override
public synchronized void setLength(int newLength) {
toStringCache = null;
super.setLength(newLength);
}
/**
* @throws IndexOutOfBoundsException {@inheritDoc}
* @see #length()
*/
@Override
public synchronized char charAt(int index) {
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
return value[index];
}
那么String为什么是不可变类?StringBuffer 和 StringBuilder为什么是可变类
查看源码
String:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
//构造方法
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
}
StringBuilder和StringBuffer
他们都继承了AbstractStringBuilder
在AbstractStringBuilder中:
abstract class AbstractStringBuilder implements Appendable, CharSequence {
/**
* The value is used for character storage.
*/
char[] value;
...
}
可以看出String中的value是常量(final)数组,只能被赋值一次。 而StringBuilder和StringBuffer就是普通的数组,所以String是不可变类,而StringBuilder和StringBuffer是可变类
三者的效率问题
如果不考虑线程安全,首选StringBuilder
大量字符串相加时,StringBuffer的append()效率远好于String对象的"+"连接
参照:https://blog.youkuaiyun.com/itchuxuezhe_yang/article/details/89966303
本文深入探讨了Java中String、StringBuffer和StringBuilder的特性与效率差异,解析了它们的内部实现机制,强调了在不同场景下选择合适字符串类的重要性。
4375

被折叠的 条评论
为什么被折叠?



