如果使用String实现String连接是使用StringBuilder实现的,那么为什么在连接期间会创建额外的对象?

use*_*526 7 java string stringbuilder

如果以下代码:

String s = "a" + 1 + "b";// 1.
Run Code Online (Sandbox Code Playgroud)

使用StringBuilder等效实现

String s = new StringBuilder().append("a").append(1).append("b");
Run Code Online (Sandbox Code Playgroud)

然后将在1中创建额外的对象"a"和"b",为什么?

jbi*_*del 5

您的示例实际上不会使用a,StringBuilder因为没有元素是变量.因为"a",1和"b"都是文字,编译器会String为你制作一个!但是,如果您在该String连接中包含一个变量,那么它将使用a StringBuilder并且需要单独的Strings用于连接元素.

对于您的示例,编译器将创建单个字符串文字:

const #2 = String       #21;    //  a1b

public void foo();
  Code:
   Stack=1, Locals=2, Args_size=1
   0:   ldc     #2; //String a1b
   2:   astore_1
   3:   return
  LineNumberTable: 
   line 7: 0
   line 8: 3
Run Code Online (Sandbox Code Playgroud)

让我们说我们已经写了

public void bar(String c)
{
    String s = "a" + c + "b";// 1.
}
Run Code Online (Sandbox Code Playgroud)

现在编译器需要创建一个StringBuilder,它将使用a和b常量ASCII文字StringBuilder.

const #20 = Asciz       a;
const #22 = Asciz       b;

public void bar(java.lang.String);
  Code:
   Stack=2, Locals=3, Args_size=2
   0:   new     #2; //class java/lang/StringBuilder
   3:   dup
   4:   invokespecial   #3; //Method java/lang/StringBuilder."<init>":()V
   7:   ldc     #4; //String a
   9:   invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava    /lang/String;)Ljava/lang/StringBuilder;
   12:  aload_1
   13:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   16:  ldc     #6; //String b
   18:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   21:  invokevirtual   #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   24:  astore_2
   25:  return
  LineNumberTable: 
   line 7: 0
   line 8: 25
Run Code Online (Sandbox Code Playgroud)


aio*_*obe 1

我觉得你有点混淆了...

对于- 情况,在评估时(就在与串联之前)+将创建一个额外的- 对象。使用该方法时可以避免这种额外的对象创建。就这样。"a1""a" + 1"a1""b"append

和将在编译时创建"a""b"(这些常量文字将从一开始就存在于字符串池中。)但正如您可能知道的那样,这些常量也会在这种append情况下创建。