What is the difference between String, StringBuilder, and StringBuffer?
All three represent strings but differ in mutability and thread safety.
String — immutable; every modification creates a new object. Stored in the String pool for literal reuse. Thread-safe by virtue of immutability.
StringBuilder — mutable, not thread-safe, but very fast. Use for string building inside a single thread (loops, builders).
StringBuffer — mutable and thread-safe (synchronized methods), so slower. Use only when multiple threads concatenate the same buffer.
// String immutability
String s = "hello";
s.concat(" world"); // Returns new String, s is unchanged!
System.out.println(s); // "hello"
s = s.concat(" world"); // Now s points to new String
System.out.println(s); // "hello world"
// StringBuilder - efficient in loops
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
sb.append(i).append(","); // Modifies in place, no new objects
}
String result = sb.toString();
// String concatenation in loop - SLOW (creates 10000 temporary Strings)
String bad = "";
for (int i = 0; i < 10000; i++) {
bad += i + ","; // Creates new String each iteration!
}
// StringBuffer - thread-safe but slower
StringBuffer buffer = new StringBuffer();
// synchronized append, insert, delete methodsString.concat returns a NEW String — the original is unchanged (immutable). StringBuilder.append modifies the buffer in place — no new objects created.
In the loop, StringBuilder creates 1 object; String concatenation creates ~10000 temporary objects. StringBuffer has the same API as StringBuilder but with synchronized methods.
The loop performance comparison is the key example. Know that the compiler optimizes a + b + c but NOT concatenation in loops.
StringBuffer is rarely needed in modern Java — prefer StringBuilder with explicit synchronization if needed.