First, String is not a mutable class. Every time you use +=
, another object is returned.
Second, unless you use that in a tight loop, it is not very important anyway.
Third, although it may not be a computer science-like approach, if I try to use
StringBuilder s = new StringBuilder("first");
s.append( "second" );
s.append( "third" );
s.append( "fourth" );
Intellij suggests to replace it with a String, and that suggestion only appears if it is at least as efficient to use a simple String (although it may not be exactly the same thing because of the conditions)
According to Java: String concat vs StringBuilder - optimised, so what should I do?
the Java compiler does replace a series of String concatenations with String builders:
public static void main(String[] args) {
String s = "first";
s+=" second" ;
if(args.length >0)
s+=" third";
System.out.println("s, = " + s);
}
Using JDK 1.8.0_66 and using javap -c SbTest.class
the following output is produced. Although I am not an expert on byte code, it seems that multiple instances of StringBuilder
are created (3
,28
). So as suggested in the linked answers, the compiled code seems to be something like:
String s = "first";
s = new StringBuilder().append(s).append(" second") ;
if(args.length >0)
s = new StringBuilder().append(s).append(" third") ;
So unless the JIT is optimizing this, it might still be more efficient to use the StringBuilder
yourself.
public static void main(java.lang.String[]);
Code:
0: ldc #2 // String first
2: astore_1
3: new #3 // class java/lang/StringBuilder
6: dup
7: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
10: aload_1
11: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
14: ldc #6 // String second
16: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
22: astore_1
23: aload_0
24: arraylength
25: ifle 48
28: new #3 // class java/lang/StringBuilder
31: dup
32: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
35: aload_1
36: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
39: ldc #8 // String third
41: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
44: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
47: astore_1
48: getstatic #9 // Field java/lang/System.out:Ljava/io/PrintStream;
51: new #3 // class java/lang/StringBuilder
54: dup
55: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
58: ldc #10 // String s, =
60: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
63: aload_1
64: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
67: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
70: invokevirtual #11 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
73: return