Counting String objects created by Java code

This Answer is to correct a misconception that is being put about by some of the other Answers:

For example:

The compiler might substitute x + y with a constant ("xyzabc"), though. @Binkan Salaryman

... and String object 4 [the String that corresponds to concatenation] can be computed by the compiler and turned into an interned constant as well. @dasblinkenlight

This is incorrect. The JLS states this:

15.18.1. String Concatenation Operator +

....

The String object is newly created (§12.5) unless the expression is a constant expression (§15.28).

In order to qualify as a constant expression, the variable names in the expression must be:

Simple names (§6.5.6.1) that refer to constant variables (§4.12.4).

where a "constant variable" is defined as:

A constant variable is a final variable of primitive type or type String that is initialized with a constant expression (§15.28).

In this example, neither x or y are final so they are not constant variables. And even if they were final, y still wouldn't be a constant variable because of the use of the new operator in its initialization.


In short, the Java compiler is not permitted to use an intern'd constant "xyzabc" as the result of the concatenation expression.

If I added the following statement at the end:

    System.out.println(x == "xyzabc");

it will always print false ... assuming that the compiler is conformant to the Java Language Specification.


By the end of the run there will be four String objects:

  1. A String that corresponds to the interned "xyz" literal
  2. Its copy created by new String("xyz")
  3. A String that corresponds to the interned "abc" literal
  4. A String that corresponds to concatenation "xyz" + "abc"

The real question is attributing some or all of these objects to your program. One can reasonably claim that as few as two or as many as four Strings are created by your code. Even though there are four String objects in total, objects 1 and 3 may not necessarily be created by your code, because they are in a constant pool, so they get created outside your code's direct control.


Take a look at decompiled class and you'll see everything :) The answer should be:

  • two strings ("xyz" and "abc") are only references to positions in constant pool so these ones are not created by your code
  • one string is created directly (new String("xyz"))
  • string concatenation is optimised by compiler and changed to StringBuilder so the last string is created indirectly

    public java.lang.String method();
    descriptor: ()Ljava/lang/String;
    flags: ACC_PUBLIC
    Code:
      stack=3, locals=3, args_size=1
     0: new           #2                  // class java/lang/String
     3: dup
     4: ldc           #3                  // String xyz
     6: invokespecial #4                  // Method java/lang/String."<init>":(Ljava/lang/String;)V
     9: astore_1
    10: ldc           #5                  // String abc
    12: astore_2
    13: new           #6                  // class java/lang/StringBuilder
    16: dup
    17: invokespecial #7                  // Method java/lang/StringBuilder."<init>":()V
    20: aload_1
    21: invokevirtual #8                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    24: aload_2
    25: invokevirtual #8                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    28: invokevirtual #9                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
    31: astore_1
    32: aload_1
    33: areturn
    

Tags:

Java

String