What is the difference between String, StringBuilder, and StringBuffer?
String, StringBuilder, and StringBuffer all represent character sequences in Java but differ critically in mutability and thread safety.
String is immutable. Every operation that appears to modify a String (concat, replace, substring) returns a new String object. The original is unchanged. Because Strings are immutable, they are inherently thread-safe, safely cacheable, and interned in the String pool for memory efficiency. The downside is that building a String with repeated concatenation inside a loop creates many intermediate objects, causing GC pressure. The JIT compiler optimizes simple loop-external concatenations using StringBuilder, but explicit StringBuilder is clearer and more efficient for loop-based construction.
StringBuilder is a mutable sequence of characters. Its internal char array can be modified in-place via append(), insert(), delete(), reverse(), and replace(). It is not thread-safe — concurrent access from multiple threads without external synchronization produces unpredictable results. StringBuilder should be the default choice for string construction within a single thread or method.
StringBuffer has the same API as StringBuilder but all its methods are synchronized, making it thread-safe. However, this synchronization has a cost — StringBuffer is measurably slower than StringBuilder in single-threaded contexts. StringBuffer was the original Java 1.0 API; StringBuilder was introduced in Java 5 as a faster single-threaded alternative. In modern Java, StringBuffer is rarely used — if you need thread-safe string construction, higher-level concurrent patterns are usually preferred over StringBuffer.
For string concatenation with the + operator: in Java 9+, the JVM uses invokedynamic and StringConcatFactory which generates efficient bytecode, making simple concatenation outside loops competitive. For building strings in loops, always prefer StringBuilder explicitly.
| Aspect | String | StringBuilder | StringBuffer |
|---|---|---|---|
| Mutability | Immutable | Mutable | Mutable |
| Thread safety | Thread-safe (immutable) | Not thread-safe | Thread-safe (synchronized) |
| Performance | Slow in loops (new objects) | Fastest | Slower (sync overhead) |
| Introduced | Java 1.0 | Java 5 | Java 1.0 |
| Storage | String pool (interning) | Heap (dynamic char array) | Heap (dynamic char array) |
| When to use | Fixed strings, keys, constants | Single-threaded string building | Rarely — legacy thread-safe building |
Correctly identifies String as immutable, StringBuilder as mutable/not thread-safe, StringBuffer as mutable/thread-safe, and explains the performance rationale.
Adds the String pool and interning, explains why StringBuffer is rarely used in modern Java, mentions Java 5 introduction of StringBuilder, and gives the + operator optimization context.
Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.
Get Graded — Free Assessment