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

10

以下三种情况中,StringBuffer转换为String的主要区别是什么:

情况1:使用toString()

StringBuffer sb = new StringBuffer("Welcome");
String st = sb.toString();

情况2:使用+""

StringBuffer sb = new StringBuffer("Welcome");
String st = sb + "";

第三种情况:使用String.valueOf()

StringBuffer sb = new StringBuffer("Welcome");
String st = String.valueOf(sb);

在性能方面使用哪种最佳实践?


其实没有什么,sb + "" 意味着调用 StringBuffer 类的 toString 方法。 - Rod_Algonquin
2个回答

9

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

2
@RajavelD 我认为 toString - MadProgrammer
1
@RajavelD 第一个,但是不太明显。我只是更喜欢它的阅读方式。 - Sotirios Delimanolis
我非常确定它编译成 new StringBuilder(String.valueOf(sb)).append("").toString(),但足够接近。 - Bohemian
3
因为sb可能为空,而编译器(创建该代码的程序)不知道/不关心sb是否为空。 String.valueOf()通过返回“null”处理空值。 - Bohemian
@Bohemian - 哦,我明白了。谢谢 :) - TheLostMind
显示剩余11条评论

6
如果我们在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;

因此,附加似乎稍微不太有效,因为它使用了额外的堆栈位并包含更多的指令。


你能告诉我如何使用“javap -v”吗? - R D
3
这是一个随JDK一起提供的命令行工具。javap -v myclass.class - Elliott Frisch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接