使用.toString(),String.valueOf()和+"将字符串缓冲区转换为字符串有什么区别? "

时间:2014-08-07 05:46:49

标签: java string stringbuilder

以下三种情况下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);

在性能方面使用哪种最佳做法?

2 个答案:

答案 0 :(得分:8)

这个

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();

答案 1 :(得分:4)

如果我们将它们编译成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;

所以附加似乎效率稍低,因为它使用额外的堆栈并包含更多指令。