What is the difference between String, StringBuilder, and StringBuffer?

7 minbeginnerstringstringbuilderstringbuffer

Quick Answer

String is immutable — every modification creates a new object, which is wasteful for repeated concatenation. StringBuilder is a mutable, growable character sequence for efficient in-place string building, but isn't thread-safe. StringBuffer is functionally identical to StringBuilder but synchronizes every method, making it thread-safe at the cost of extra overhead — usually unnecessary, since a StringBuffer is rarely actually shared across threads mid-construction.

Detailed Answer

StringStringBuilderStringBuffer
Mutabilityimmutablemutablemutable
Thread safetysafe (immutable, inherently)not synchronizedsynchronized (thread-safe)
Performancefine for few/no modificationsfastest for building/modifyingslower than StringBuilder due to lock overhead
Introducedsince 1.0Java 5since 1.0

String's immutability means every +/concat/replace call allocates a new String object. That's fine for one-off operations, but wasteful in a loop:

String s = "";
for (int i = 0; i < 1000; i++) {
    s += i; // creates ~1000 intermediate String objects — O(n²) overall
}

StringBuilder avoids this by mutating an internal, resizable character array in place:

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i); // mutates in place — no new object per iteration
}
String result = sb.toString();

StringBuffer behaves identically to StringBuilder, but synchronizes every method, making it safe to share across threads. In practice, though, a StringBuilder/StringBuffer is almost always built up and converted to a final String entirely within one thread or method before being shared — so that synchronization overhead is rarely worth paying. StringBuilder is the default recommendation for essentially all new code. StringBuffer mostly persists for legacy code and rare, genuinely shared-mutable-buffer scenarios.

Note: the compiler automatically optimizes simple, single-expression string concatenation ("a" + b + "c") into efficient StringBuilder calls internally. The manual StringBuilder concern is specifically about concatenation spread across a loop, or built up incrementally across multiple statements.