String、StringBuffer和StringBuilder

整理一下近期学习的String、StringBuffer和StringBuilder之间的区别

执行速度:String < StringBuffer < Stringbuilder

String与StringBuffer和StringBuilder之间的区别

  • String:字符串常量
  • StringBuffer:字符串变量
  • StringBuilder:字符串变量

我们知道String是常量,常量是不可以修改的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void main(String[] args){
String str = "123";
change(str);
System.out.println(str);
}

public static void change(String s){
System.out.println(s);
s = s + "abc";
system.out.println(s);
}
/*console:
123
123abc
123*/

可以看到change方法并没有起到效果。

  1. 调用change方法时,str和s都指向”123”
  2. 当执行s = s + "abc"时s指向了”123abc” ,str还是指向”123”
1
2
3
String s = "123";
s = s + "abc";
System.out.print(s); //result : 123abc

既然是常量,那为什么这里还可以对常量进行操作呢?
JVM会创建一个新的字符串常量,原来的字符串常量成为垃圾被GC回收掉。
StringBuffer和StringBuilder是字符串变量,对他们的操作是在原对象上进行的操作。

所以执行速度:String < StringBuffer < Stringbuilder

特例

1
2
String Str = "123" + "abc" + "123abc";
StringBuffer Strb = new StringBuffer("123").append("abc").append("123abc");

上面两个字符串生成的速度并不像预期的那样,StringBuffer 快于 String。为什么?
因为JVM在创建字符串常量时

1
2
3
String Str = "123" + "abc" + "123abc";
//就等于
String Str = "123abc123abc";

所以直接被创建出来,速度很快。
但是如果分步执行,就会按照JVM对常规字符串常量的操作,创建新常量,回收旧常量的方式进行操作。