How many Strings does this create?
String test(String text) {
return "string 1 " +
text + " string 2 " +
"string 3";
}
How many Strings does this create?
String test(String text) {
return "string 1 " +
text + " string 2 " +
"string 3";
}
No new String calls are present here, the only one that exists is in StringBuilder.toString, so
1
java.lang.String test(java.lang.String);
Code:
Stack=3, Locals=2, Args_size=2
0: new #16; //class java/lang/StringBuilder
3: dup
4: ldc #18; //String string 1
6: invokespecial #20; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
9: aload_1
10: invokevirtual #23; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
13: ldc #27; //String string 2
15: invokevirtual #23; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
18: ldc #29; //String string 3
20: invokevirtual #23; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
23: invokevirtual #31; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
26: areturn
This is pretty easy to answer by compiling the code, then inspecting the bytecode with javap -c. In this particular case, the compiler should generate code like
String result = new StringBuilder("string1").
append(text).append("string2").append("string3").toString();
so depending on how you look at it, you might say only one, or if you're one of those people who likes to count literals as being "created" when they're used, you could say four.
javapis your friend. I put your code into S.java and deassembled it using javap -c S:
Compiled from "S.java"
public class S extends java.lang.Object{
public S();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public java.lang.String test(java.lang.String);
Code:
0: new #2; //class java/lang/StringBuilder
3: dup
4: invokespecial #3; //Method java/lang/StringBuilder."<init>":()V
7: ldc #4; //String string 1
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 string 2
18: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: ldc #7; //String string 3
23: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
26: invokevirtual #8; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
29: areturn
}
With OpenJDK 1.6.0_22 there is only one StringBuilder and one String created.
this is the equivalent of
(new StringBuilder((new StringBuilder((new StringBuilder("String 1")).append(text).toString())).append("string 2 ").toString()).append("string 3").toString();
that's 3 stringbuilders and 6 strings. The way to optimize this is:
StringBuilder sb = new StringBuilder("string 1");
sb.append(test);
sb.append(" string 2 ");
sb.append("string 3");
return sb.toString();
StringBuilder is constructed, and append is called for each subsequent string. The code you've shown as being "optimized" is actually what the compiler emits. Check it out using javap -c.