Why Java Creates a Single String Object on Concatenation – Exploring Constant Folding
This article explains how Java’s compiler applies constant folding to compile‑time constants, turning string concatenations like "a"+"b"+"c" into a single String object, distinguishes compile‑time versus runtime constants, and demonstrates the impact on the constant pool and equality comparisons.
First, consider a common interview question: how many String objects are created by the following code? String s = "a" + "b" + "c"; Decompiling the bytecode shows that only one String object is created.
The reason is that the compiler performs constant folding , evaluating compile‑time constant expressions during compilation and replacing them with the computed value.
A compile‑time constant must satisfy:
be declared final be of a primitive type or String be initialized at the point of declaration
be initialized with a constant expression
Examples:
final String s1 = "hello " + "Hydra";
final String s2 = UUID.randomUUID().toString() + "Hydra";Here s1 is a compile‑time constant whose value is "hello Hydra", while s2 is not, because its initializer is not a constant expression; it is a runtime constant.
The compiled constant pool contains only the literal "hello Hydra" as a String entry; the value of s2 does not appear there.
Adding final can also affect class initialization. In the first run the class‑initialization block prints a message, while in the second run (with final on the static field) it does not.
public class IntTest1 {
public static void main(String[] args) {
System.out.println(a1.a);
}
}
class a1 {
static {
System.out.println("init class");
}
public static int a = 1;
}Running the code prints:
init class
1Further examples demonstrate that a final String variable initialized with another variable is not a compile‑time constant, so the concatenated result is not folded:
final String h1 = "hello";
String h2 = "hello";
String s1 = h1 + "Hydra";
String s2 = h2 + "Hydra";
System.out.println(s1 == "helloHydra"); // true
System.out.println(s2 == "helloHydra"); // falseWhen a string is built from literals only, the compiler folds it; otherwise it creates a new object via StringBuilder, which explains why s2 == "ab" yields false while s3 == "ab" yields true in the following example:
String s1 = "a";
String s2 = s1 + "b";
String s3 = "a" + "b";
System.out.println(s2 == "ab"); // false
System.out.println(s3 == "ab"); // trueThe article also lists the kinds of expressions that the Java Language Specification considers constant expressions, such as literals, casts, unary operators (excluding ++ and --), binary arithmetic operators, and shift operators.
Finally, it notes that literals are stored in the constant pool, and that the null literal can be assigned to any reference type.
All code was tested on Java 1.8.0_261‑b12.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Su San Talks Tech
Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
