对于以下三种情况,将StringBuffer转换为String的主要区别是什么:
案例1:使用toString()
StringBuffer sb = new StringBuffer("Welcome");
String st = sb.toString();
案例2:使用+ "
StringBuffer sb = new StringBuffer("Welcome");
String st = sb + "";
案例3:使用String.valueOf()
StringBuffer sb = new StringBuffer("Welcome");
String st = String.valueOf(sb);
在性能方面使用哪个是最佳实践?
This
StringBuffer sb = new StringBuffer("Welcome");
String st = sb + "";
或多或少会导致
StringBuffer sb = new StringBuffer("Welcome");
StringBuilder builder = new StringBuilder();
builder.append((sb == null) ? "null" : sb.toString());
builder.append("");
String st = builder.toString();
如果我们在java中将它们编译成两个方法
private StringBuffer sb = new StringBuffer("Welcome");
public String testToString() {
return sb.toString();
}
public String testAppend() {
return sb + "";
}
然后使用javap -v
,我们得到
public java.lang.String testToString();
descriptor: ()Ljava/lang/String;
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: getfield #19 // Field sb:Ljava/lang/StringBuffer;
4: invokevirtual #27 // Method java/lang/StringBuffer.toString:()Ljava/lang/String;
7: areturn
LineNumberTable:
line 10: 0
LocalVariableTable:
Start Length Slot Name Signature
0 8 0 this Lcom/stackoverflow/Question;
public java.lang.String testAppend();
descriptor: ()Ljava/lang/String;
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: new #31 // class java/lang/StringBuilder
3: dup
4: invokespecial #33 // Method java/lang/StringBuilder."<init>":()V
7: aload_0
8: getfield #19 // Field sb:Ljava/lang/StringBuffer;
11: invokevirtual #34 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
14: invokevirtual #38 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
17: areturn
LineNumberTable:
line 14: 0
LocalVariableTable:
Start Length Slot Name Signature
0 18 0 this Lcom/stackoverflow/Question;
所以追加似乎效率稍低,因为它使用了额外的堆栈位并包含了更多的指令。