Java String Interning代码差异及编译/运行时判定原因问询
Great question! Let's break this down clearly to understand why these two Java string snippets behave differently with string interning.
Core Difference: Compile-Time Constant vs. Runtime Dynamic Value
The key distinction here boils down to whether the final string value can be determined at compile time or only at runtime—and how Java's compiler and string pool optimize around that.
1. Why String s1 = "hel" + "lo"; gets auto-interned
- Java’s compiler uses an optimization called constant folding: when you concatenate string literals (hardcoded with double quotes) directly, the compiler merges them into a single literal during compilation.
- So under the hood, this line compiles exactly the same as
String s1 = "hello";. - By Java’s default behavior, all string literals are automatically added to the String Pool (the area of memory where unique string values are stored to save space)—this is what "interning" means here.
- You can confirm this with
javap -c(view bytecode): you’ll see the code directly loads the constant"hello"instead of handling two separate strings.
2. Why String s1 = "lo"; String s2 = "hel" + s1; doesn’t get auto-interned
- Here,
s1is a variable. Even though we initialize it to"lo", the compiler can’t guarantee this value won’t change before the concatenation (for example, another line of code could reassigns1to a different string). - Because the compiler can’t know the final value of
s1at compile time, it can’t pre-fold"hel" + s1into"hello". Instead, at runtime, Java uses aStringBuilder(or similar mechanism) to build the string dynamically, creating a newStringobject that lives in the regular heap—not the String Pool. - Check the bytecode with
javap -c, and you’ll see instructions for creating aStringBuilder, callingappend()twice, and thentoString()—no pre-computed constant here.
3. Why the compile-time vs. runtime distinction matters
- The String Pool is a memory optimization: it stores only one copy of each unique string to avoid redundant objects. But this optimization only works for values the compiler can confirm are fixed.
- For runtime-generated strings, Java can’t predict their content ahead of time, so it can’t pre-populate them in the pool. Auto-interning every runtime string would also bloat the pool and defeat its purpose.
- A quick side note: if you mark
s1asfinal(likefinal String s1 = "lo";), it becomes a compile-time constant. The compiler can then safely fold"hel" + s1into"hello", ands2will point to the interned pool version—just like the first example! That’s becausefinalguarantees the variable’s value will never change.
内容的提问来源于stack exchange,提问作者Soumyadeep Ganguly
相关产品推荐
相关产品推荐

