StringBuffer类与StringBuilder类
public class Test {
public static void main(String[] args) {
/* 此处的
String s1 = "abc";
String s2 = "abc";
可以将s1和s2理解为基本数据类型的变量
“abc”可以理解为基本数据类型的常量
所以s1和s2这两个变量所存储的都是”abc“在字符串常量池中的地址*/
String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2); //true
System.out.println(s1.equals(s2)); //true
System.out.println("===========");
//s3和s4存的是对象的地址
String s3 = new String("abc");
System.out.println(s1 == s3); //false
System.out.println(s1.equals(s3)); //true
System.out.println("===========");
String s4 = new String("abc"); //false
System.out.println(s3 == s4); //true
System.out.println(s3.equals(s4));
//我们对字符串本身不能修改 所以想要扩展字符串内容的话 只能重新创建一个字符串
//出现了临时字符串 也就是下文中的haha
//临时字符串越多 也就意味着字符串常量池中没有被引用的字符串越多 垃圾就越多 如何进行优化
String s5 = s1 + "haha";
System.out.println(s1 == s5); //false
}
}
如果说String是固定长度的且不能修改内容的字符串
那么SB就是长度可以改变且能够修改内容的字符串
StringBuffer和StringBuilder 也称之为字符串缓冲区 唯一的区别就在适用的场景不同,StringBuffer适用于多线程StringBuilder适用于单线程
StringBuilder是线程不安全的——没加锁(同步锁) 单线程 效率会更高
StringBuffer是线程安全的——加锁(同步锁) 多线程 效率会更低
虽然SB从名字上看和String有关系 但是不是有关系
StringBulider (成员函数没有synchronized修饰 无同步锁)
public final class StringBuilder//有final表示不能被继承
extends AbstractStringBuilder
implements Serializable, CharSequence
StringBuffer(成员函数都有synchronized修饰 有同步锁)
public final class StringBuffer//有final表示不能被继承
extends AbstractStringBuilder
implements Serializable, CharSequence
String(线程不安全 会产生额外垃圾)
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence
String和SB本质上都是字符数组
String中不支持字符数组扩容和修改内容 SB中支持字符数组扩容和修改内容 SB——字符缓冲区其实就是个动态扩容的数组而已 如果扩容次数越多,那么也意味着所用过的数组也越多 垃圾越多
String也会产生垃圾
SB产生的垃圾主要集中在堆内存,String产生的垃圾主要集中在方法区(字符串常量池)
JVM,GC在堆内存中活跃程度比在方法区的活跃成都要大的多(GC即是垃圾收集器)
也就意味着GC在堆内存中回收垃圾的效率要远远在比方法区高
堆的垃圾被回收的很快 方法区的垃圾回收的很慢
也就意味着GC在堆内存中回收垃圾的效率要远远在比方法区高
堆的垃圾被回收的很快 方法区的垃圾回收的很慢
综上,推荐使用SB