The background,

When writing code that uses StringBuilder for String concatenation, IDEA will probably prompt: ‘StringBuilder’ can be replaced with ‘String’.

So why is this hint given? What does this hint mean?

Second, the thinking

As I said earlier, “Behind every question lies at least one blind spot and opportunity for learning.” So we’re not going to let this opportunity go lightly.

In addition a lot of people this time may be about to start Baidu!

Stop!!

“Alibaba Java development manual” detailed explanation column has talked about the “first guess after verification” idea, to learn the source code has a lot of help, so will be more impressive.

‘StringBuilder’ can be replaced with ‘String’. Replace StringBuilder with String.

We know that the reason we use StringBuilder is to avoid creating a lot of unnecessary string objects during string concatenation.

So the fact that we can replace it with String means that in this case they’re probably equivalent, which means that the bottom layer is the same.

Three, the analysis

“Alibaba Java development Manual” detailed explanation “column has said to write DEMO, decompilation and disassembly is an important means of learning.

Let’s write a DEMO to verify this:

public class StringDemo {

    public static void main(String[] args) {
        String a = "a";
        Integer b = 0;
        Long c = 1000L;
        useStringBuilder(a, b, c);
        usePlus(a, b, c);
    }

    /** * Use StringBuilder to concatenate */
    private static void useStringBuilder(String a, Integer b, Long c) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(a).append(b).append(c);
        System.out.println(stringBuilder.toString());
    }

    /** * string concatenation */ with the + sign
    private static void usePlus(String a, Integer b, Long c) { System.out.println(a + b + c); }}Copy the code

Using the decompiler tool that comes with IDEA, the source code is almost identical (not shown here).

Next, try disassembling Javap -c -p StringDemo(already compiled with Javac) :

public class com.chujianyun.common.str.StringDemo { public com.chujianyun.common.str.StringDemo(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: ldc #2 // String a 2: astore_1 3: iconst_0 4: invokestatic #3 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 7: astore_2 8: ldc2_w #4 // long 1000l 11: invokestatic #6 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long; 14: astore_3 15: aload_1 16: aload_2 17: aload_3 18: invokestatic #7 // Method useStringBuilder:(Ljava/lang/String; Ljava/lang/Integer; Ljava/lang/Long;) V 21: aload_1 22: aload_2 23: aload_3 24: invokestatic #8 // Method usePlus:(Ljava/lang/String; Ljava/lang/Integer; Ljava/lang/Long;) V 27: return private static void useStringBuilder(java.lang.String, java.lang.Integer, java.lang.Long); Code: 0: new #9 // class java/lang/StringBuilder 3: dup 4: invokespecial #10 // Method java/lang/StringBuilder."<init>":()V 7: astore_3 8: aload_3 9: aload_0 10: invokevirtual #11 // Method java/lang/StringBuilder.append:(Ljava/lang/String;) Ljava/lang/StringBuilder; 13: aload_1 14: invokevirtual #12 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;) Ljava/lang/StringBuilder; 17: aload_2 18: invokevirtual #12 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;) Ljava/lang/StringBuilder; 21: pop 22: getstatic #13 // Field java/lang/System.out:Ljava/io/PrintStream; 25: aload_3 26: invokevirtual #14 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 29: invokevirtual #15 // Method java/io/PrintStream.println:(Ljava/lang/String;) V 32: return private static void usePlus(java.lang.String, java.lang.Integer, java.lang.Long); Code: 0: getstatic #13 // Field java/lang/System.out:Ljava/io/PrintStream; 3: new #9 // class java/lang/StringBuilder 6: dup 7: invokespecial #10 // Method java/lang/StringBuilder."<init>":()V 10: aload_0 11: invokevirtual #11 // Method java/lang/StringBuilder.append:(Ljava/lang/String;) Ljava/lang/StringBuilder; 14: aload_1 15: invokevirtual #12 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;) Ljava/lang/StringBuilder; 18: aload_2 19: invokevirtual #12 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;) Ljava/lang/StringBuilder; 22: invokevirtual #14 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 25: invokevirtual #15 // Method java/io/PrintStream.println:(Ljava/lang/String;) V 28: return }Copy the code

Note: You can also view bytecodes using the Jclasslib bytecode plug-in recommended in the first bonus article of this column

If you compare the bytecode instructions of usePlus and useStringBuilder, you will find that the + sign concatenation method with variables will eventually be converted to StringBuilder for concatenation of strings.

This is equivalent to compiler optimizations, so IDEA detects that they are equivalent and gives this hint to make the code more concise.

To verify this idea again, open the Java Language Specification 15.18.1.String Concatenation Operator + :

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.

Java language implementations can choose to perform conversions and concatenations in a step to avoid creating and then discarding intermediate string objects. To improve the performance of String concatenation operations, the Java compiler can use the functional StringBuilder class or similar techniques to reduce the number of intermediate Strings created when evaluating expressions.

So the question is clear.

Four,

I’ve previously written why We Recommend Learning Bytecode and Every question Hides at least one Blind Spot and A Great Opportunity to Learn. I want you to really understand the usefulness of learning bytecode; Can really grasp every question, through the in-depth exploration of each question to thoroughly grasp a certain knowledge. The Java Language Specification and the Java Virtual Specification are also highly recommended as they are more comprehensive and authoritative.

I hope this article will be helpful. Please follow my column and leave a comment if you have any questions to share with me.