stringbuilder调用中的Java字符串concat

zel*_*ler 5 java string stringbuilder

据我所知,StringBuilder通过在concats期间不在字符串池中创建临时字符串实例来帮助减少内存使用量.但是,如果我这样做会发生什么:

StringBuilder sb = new StringBuilder("bu");
sb.append("b"+"u");
Run Code Online (Sandbox Code Playgroud)

它编译成了吗?

sb.append("b");
sb.append("u");
Run Code Online (Sandbox Code Playgroud)

?或者它取决于优化标志?或者,如果使用stringbuilders,我会失去整个好处?或者这个排队没有意义?:)

JB *_*zet 8

它编译为sb.append("bu"),因为编译器将多个String litterals的串联转换为单个String litteral.

如果你有

String a = "a";
sb.append(a + "b");
Run Code Online (Sandbox Code Playgroud)

它会编译成

String a = "a";
String temp = a + "b"; // useless creation of a string here
sb.append(temp);
Run Code Online (Sandbox Code Playgroud)

所以你应该更喜欢

sb.append(a);
sb.append("b");
Run Code Online (Sandbox Code Playgroud)

在这种情况下.

  • 不,这不是新的.能够正确格式化(在几行上)长字符串文字,例如长SQL或JPQL查询,这非常有用. (2认同)

aio*_*obe 7

因为"b" + "u"是一个在编译时计算的表达式,所以它将被编译,就像你有"bu".

 0: new #2; //class StringBuilder
 3: dup
 4: ldc #3; //String bu
 6: invokespecial   #4; //Method StringBuilder."<init>":(String;)V
 9: astore_1
10: aload_1
11: ldc #3; //String bu
13: invokevirtual   #5; // StringBuilder.append:(String;)LStringBuilder;
Run Code Online (Sandbox Code Playgroud)

另一方面,如果您有两个字符串变量,则此优化不会启动:

以下片段......

StringBuilder sb = new StringBuilder("bu");
String b = "b", u = "u";

sb.append(b + u);
Run Code Online (Sandbox Code Playgroud)

...编译为:

0:  new #2; //class StringBuilder
3:  dup
4:  ldc #3; //String bu
6:  invokespecial   #4; //Method StringBuilder."<init>":(String;)V
9:  astore_1
10: ldc #5; //String b
12: astore_2
13: ldc #6; //String u
15: astore_3
16: aload_1
17: new #2; //class StringBuilder
20: dup
21: invokespecial   #7; //Method StringBuilder."<init>":()V
24: aload_2
25: invokevirtual   #8; //Method StringBuilder.append:(String;)StringBuilder;
28: aload_3
29: invokevirtual   #8; //Method StringBuilder.append:(String;)StringBuilder;
32: invokevirtual   #9; //Method StringBuilder.toString:()String;
35: invokevirtual   #8; //Method StringBuilder.append:(String;)StringBuilder;
Run Code Online (Sandbox Code Playgroud)

即类似的东西

StringBuilder sb = new StringBuilder("bu");
String b = "b", u = "u";

StringBuilder temp = new StringBuilder();
temp.append(b);
temp.append(b);
String result = temp.toString();

sb.append(result);
Run Code Online (Sandbox Code Playgroud)

正如您在第17-21行中所看到的,StringBuilder为了连接a和创建了额外的内容b.然后,在第32行上获取String此临时结果,StringBuilder并将其附加到第StringBuilder35行的原始内容.


(字节码是由javap命令生成的,它是JDK的一部分.尝试一下,它非常简单!)