Java string concat in stringbuilder call

烂漫一生 提交于 2020-01-03 13:09:09

问题


As far as I know, StringBuilder helps to reduce memory usage by not creating temporary string instances in the string pool during concats. But, what happens if I do sth like this:

StringBuilder sb = new StringBuilder("bu");
sb.append("b"+"u");

Does it compile into

sb.append("b");
sb.append("u");

? Or it depends on optimalization flags? Or I loose the whole benefit if stringbuilders? Or this quetion makes no sense? :)


回答1:


It compiles to sb.append("bu"), because the compiler translates the concatenation of multiple String litterals to a single String litteral.

If you had

String a = "a";
sb.append(a + "b");

it would compile it to

String a = "a";
String temp = a + "b"; // useless creation of a string here
sb.append(temp);

So you should prefer

sb.append(a);
sb.append("b");

in this case.




回答2:


Since "b" + "u" is an expression which is evaluated at compile time, it will be compiled just as if you had "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;

If you on the other hand had two string variables, this optimization wouldn't kick in:

The following snippet...

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

sb.append(b + u);

...gets compiled as:

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;

I.e. something similar to

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

As you can see in line 17-21 an extra StringBuilder is created for the purpose of concatenating a and b. The resulting String of this temporary StringBuilder is then fetched on line 32 and appended to the original StringBuilder on line 35.


(The bytecode was generated by the javap command which is part of the JDK. Try it out, it's really simple!)




回答3:


No, the "b" + "u" will create an immutable b string, an immutable u string, and then create a third immutable bu string that gets passed into the StringBuilder instance.




回答4:


WRONG:

StringBuilder sb = new StringBuilder();
sb.append("b"+"u");

CORRECT:

StringBuilder sb = new StringBuilder();
sb.append("b").append("u");

BEST: //Since you knew what's going to be in there already! ;)

StringBuilder sb = new StringBuilder();
sb.append("bu");

:)

EDIT

I guess my answer above is not correct when dealing with literals only...

:/



来源:https://stackoverflow.com/questions/7663252/java-string-concat-in-stringbuilder-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!