Search code examples
javastringconcatenationstring-pool

Java Strings Concatenation and Objects


How many objects will be created for the following code?

String temp = "a" + "b" + "c"

My understanding: a,b and c are string literals and will be stored on the string pool (so no new object created). Then while appending using "+" operator it uses StringBuffer internally so 1 object will be created which will hold "abc"(StringBuffer). And it will be returned in a new String object (Whose value will be "abc").

-> So as per me total 2 objects will be created during this operation.(one String and one StringBuffer).

-> Also String "abc" will NOT be present in String Pool.

Am I wrong?


Solution

  • From this test code:

    public class Test {
        public static void main(final String[] args) {
            String temp = "a" + "b" + "c";
        }
    }
    

    You get this bytecode:

    public static void main(java.lang.String[]);
      Code:
         0: ldc           #2                  // String abc
         2: astore_1      
         3: return 
    

    With this constant pool:

    Constant pool:
       #1 = Methodref          #4.#13         //  java/lang/Object."<init>":()V
       #2 = String             #14            //  abc
       #3 = Class              #15            //  Test
       #4 = Class              #16            //  java/lang/Object
       #5 = Utf8               <init>
       #6 = Utf8               ()V
       #7 = Utf8               Code
       #8 = Utf8               LineNumberTable
       #9 = Utf8               main
      #10 = Utf8               ([Ljava/lang/String;)V
      #11 = Utf8               SourceFile
      #12 = Utf8               Test.java
      #13 = NameAndType        #5:#6          //  "<init>":()V
      #14 = Utf8               abc
      #15 = Utf8               Test
      #16 = Utf8               java/lang/Object
    

    So you were incorrect. One String was created -- "abc" -- and placed into the String pool at runtime.

    The compiler here performed constant folding and simplified the compile-time constant expression "a" + "b" + "c" to "abc". You can see this if you compile with the -XD-printflat flag, which shows the actual source that the compiler compiles to bytecode:

    public static void main(final String[] args) {
        String temp = "abc";
    }
    

    If you want to see actual String concatenation, you'll have to work with operands that aren't compile-time constants, such as variables:

    public static void main(final String[] args) {
        String a = "a";
        String b = "b";
        String c = "c";
        String temp = a + b + c;
    }
    

    Gets compiled to:

    public static void main(java.lang.String[]);
      Code:
         0: ldc           #2                  // String a
         2: astore_1      
         3: ldc           #3                  // String b
         5: astore_2      
         6: ldc           #4                  // String c
         8: astore_3      
         9: new           #5                  // class java/lang/StringBuilder
        12: dup           
        13: invokespecial #6                  // Method java/lang/StringBuilder."<init>":()V
        16: aload_1       
        17: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        20: aload_2       
        21: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        24: aload_3       
        25: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        28: invokevirtual #8                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        31: astore        4
      33: return