I was looking at the String
Javadoc when I noticed this bit about String concatenation:
The Java language provides special support for the string
concatenation operator ( + ), and for conversion of other objects to
strings. String
concatenation is implemented through the
StringBuilder
(or StringBuffer
)
From the Java 8 JLS 15.8.1, it is a choice given to the compiler (emphasis mine):
An implementation may choose to perform conversion and concatenation
in one step to avoid creating and then discarding an intermediate
String object. To increase the performance of repeated string
concatenation, a Java compiler may use the StringBuffer class or a
similar technique to reduce the number of intermediate String objects
that are created by evaluation of an expression.
I made a small program to see what it compiles down to
public class Tester {
public static void main(String[] args) {
System.out.println("hello");
for (int i = 1; i < 5; i++) {
String s = "hi " + i;
System.out.println(s);
}
String t = "me";
for (int i = 1; i < 5; i++) {
t += i;
System.out.println(t);
}
System.out.println(t);
}
}
And the output when running javap -c Tester
shows that StringBuilder
is being used:
Compiled from "Tester.java"
public class Tester {
public Tester();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String hello
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: iconst_1
9: istore_1
10: iload_1
11: iconst_5
12: if_icmpge 48
15: new #5 // class java/lang/StringBuilder
18: dup
19: invokespecial #6 // Method java/lang/StringBuilder."<init>":()V
22: ldc #7 // String hi
24: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
27: iload_1
28: invokevirtual #9 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
31: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
34: astore_2
35: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
38: aload_2
39: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
42: iinc 1, 1
45: goto 10
48: ldc #11 // String me
50: astore_1
51: iconst_1
52: istore_2
53: iload_2
54: iconst_5
55: if_icmpge 90
58: new #5 // class java/lang/StringBuilder
61: dup
62: invokespecial #6 // Method java/lang/StringBuilder."<init>":()V
65: aload_1
66: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
69: iload_2
70: invokevirtual #9 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
73: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
76: astore_1
77: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
80: aload_1
81: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
84: iinc 2, 1
87: goto 53
90: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
93: aload_1
94: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
97: return
}
I've looked at a handful of questions that tell the story that StringBuilder
is generally faster because of synchronization in StringBuffer
, and that is substituted for these string concatenations:
- When is StringBuffer/StringBuilder not implicitly used by the compiler?
- What happens when Java Compiler sees many String concatenations in one line?
- Java: String concat vs StringBuilder - optimised, so what should I do?
- Best practices/performance: mixing StringBuilder.append with String.concat
- StringBuilder vs String concatenation in toString() in Java
- StringBuilder and StringBuffer
So, considering the things I've read that show that StringBuilder
is generally the better choice leads me to wonder a couple things:
- When and why would a compiler choose to use
StringBuffer
instead of StringBuilder
?
- Wouldn't it make more sense if the compiler had the choice of using any
AbstractStringBuilder
implementation?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…