String Literal Concatenation
When concatenating string literals at compile time, the operation is optimized during the compilation phase before the bytecode is generated. This optimization occurs when all operands are known constants.
During this process, the compiler pre-computes the concatenated result and stores it in the constant pool. Both variables referencing the same literal sequance will point to identical objects in the string constant pool, making equality comparisons return true.
Mixed Literal and Variable Concatenation
When string concatenation involves atleast one variable, the operation behaves differently. The result is allocated in the heap memory rather than the constant pool.
The underlying mechanism involves creating a StringBuilder instance, appending each operand using its append() methods, and finally invoking toString() to produce the resulting string object.
public void demonstrateConcatenation() {
String first = "x";
String second = "y";
String combinedLiteral = "xy";
String runtimeConcat = first + second;
System.out.println(combinedLiteral == runtimeConcat); // Returns false
}
Bytecode analysis reveals the implementation:
0 ldc #5 <x>
2 astore_1
3 ldc #6 <y>
5 astore_2
6 ldc #7 <xy>
8 astore_3
9 new #8 <java/lang/StringBuilder>
12 dup
13 invokespecial #9 <java/lang/StringBuilder.<init>>
16 aload_1
17 invokevirtual #10 <java/lang/StringBuilder.append>
20 aload_2
21 invokevirtual #10 <java/lang/StringBuilder.append>
24 invokevirtual #11 <java/lang/StringBuilder.toString>
27 astore 4
...
The execution flow:
- Load string constants "x" and "y" from the constant pool into local variables
- Load the pre-computed literal "xy" into another variable
- Create a new StringBuilder instance via its constructor
- Push the variable values onto the operand stack
- Invoke append() methods to concatenate the strings
- Call toString() to generate a new String object in heap memory
Critical distinction: The StringBuilder's toString() method creates strings through character array construction rather than literal instantiation. Since no explicit string literal syntax appears in the source code for dynamically concatenated results, these objects exist solely in heap memory without corresponding entries in the string constant pool.
Consequently, combinedLiteral references an object in the constant pool while runtimeConcat points to a heap-allocated object, causing the reference equality check to return false.