StringBuilder的append参数是否为新String对象?循环对象创建与GC疑问
Great question—this is a super common gotcha with Java strings and StringBuilder, so let's unpack it all clearly:
1. Is the parameter passed to StringBuilder.append() a new String object?
It depends entirely on where that parameter comes from:
- If you're passing a string literal (like
" "in your example), it's pulled from the string constant pool—not a new object (unless it's the first time that literal is used in your program, in which case it gets added to the pool first). - If you're passing a dynamically generated string (like the result of
i + " "orString.valueOf(i)), that is a brand-new String object stored on the heap (it won't be in the constant pool unless you explicitly callintern()on it).
2. Will these parameter objects be garbage collected?
Yes—if there are no other references to them. When you pass a String to append(), the method only copies the character data from the String into StringBuilder's internal char array. Once the append() call finishes, if nothing else is holding a reference to that parameter String (like a class-level variable or a reference in the constant pool), it becomes unreachable from GC roots and is eligible for garbage collection.
3. Does i + " " create two GC-eligible String objects per loop iteration?
You're exactly right—let's walk through what happens when the JVM executes sb.append(i + " "):
- First,
i(an int) gets converted to a String viaString.valueOf(i). This creates a new String object (let's call its1) representing the numeric value ofi. - Next, the JVM handles the
+concatenation by creating a temporaryStringBuilder, appendings1and the pool-based" ", then callingtoString()on that temporary builder. ThistoString()call creates a second new String object (s2) with the combined value (like"0 ","1 ", etc.). - Finally,
s2is passed tosb.append(), which copies its characters into your main StringBuilder. After this, neithers1nors2have any remaining references—they're both just floating on the heap, waiting to be collected.
So each loop iteration creates two distinct String objects that are eligible for GC (assuming no GC runs mid-loop).
Quick note on the OCA manual's "~1000 objects" comment
The manual might be simplifying things by focusing only on the final concatenated string (s2) instead of both s1 and s2. Or it could be referencing older Java versions where some optimizations reduced the count—but from a strict execution perspective, your reasoning about two GC-eligible objects per iteration is correct.
Also, to confirm the other points you mentioned:
- Your main
StringBuilderstays as a single object the whole time—append()just modifies its internal array (and resizes it if needed), no new builder is created. - The
" "literal is reused from the string pool, so only one instance of that exists throughout the program.
内容的提问来源于stack exchange,提问作者user5488307

