Perfect — this is another super common interview question, and understanding this difference is key for writing efficient and thread-safe string manipulation code in Java.
📊 Quick Comparison Table
| Feature | String | StringBuilder | StringBuffer |
|---|---|---|---|
| Mutability | ❌ Immutable | ✅ Mutable | ✅ Mutable |
| Thread-safety | ✅ Thread-safe (immutable) | ❌ Not thread-safe | ✅ Thread-safe (synchronized methods) |
| Performance | 🐢 Slow (new object for every modification) | 🚀 Fast | 🐌 Slower than StringBuilder (due to synchronization) |
| Introduced in | Java 1.0 | Java 1.5 | Java 1.0 |
| Best for | Constant strings, keys, messages | Single-threaded string modification | Multi-threaded string modification (rarely needed) |
🔎 Explanation of Each
1️⃣ String (Immutable)
- Once created, a
Stringcannot be changed. - Every modification (
concat,replace,toUpperCase, etc.) creates a newStringobject. - Stored in String Pool if created using string literals.
Example:
String s = "Hello";
s = s + " World"; // Creates a new String — "Hello" is discarded
✅ Use String when:
- Content never changes (e.g., constant values, configuration keys).
- You need thread safety automatically (because immutable objects are inherently thread-safe).
2️⃣ StringBuilder (Mutable and Fast)
- Can change contents directly without creating new objects.
- Faster than
Stringfor frequent modifications. - Not thread-safe, so only use in single-threaded environments.
Example:
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World"); // Same object is modified
✅ Use StringBuilder when:
- String needs frequent changes (e.g., loops, file parsing, JSON building).
- Performance is important.
- Thread safety is not required.
3️⃣ StringBuffer (Mutable and Thread-safe)
- Almost identical to
StringBuilder, but all methods are synchronized. - This makes it thread-safe, but slower.
- Rarely needed nowadays because you usually avoid shared mutable state across threads.
Example:
StringBuffer sb = new StringBuffer("Hello");
sb.append(" World"); // Same object, thread-safe
✅ Use StringBuffer when:
- You absolutely need string modification across multiple threads.
- You are maintaining very old legacy code (modern apps rarely use
StringBuffer).
🏁 Performance Comparison (General Rule)
| Case | Best Choice |
|---|---|
| Simple string manipulation | String |
| Frequent changes (single-threaded) | StringBuilder |
| Frequent changes (multi-threaded) | StringBuffer (only if absolutely needed) |
🔥 Quick Mnemonic to Remember
| Class | Rule |
|---|---|
| String | Immutable & Safe |
| StringBuilder | Mutable & Fast |
| StringBuffer | Mutable & Thread-Safe (but slow) |
💡 Important Note for Modern Java
✅ Use StringBuilder in 95% of cases needing modifications.
✅ Use String for constants, messages, and keys.
✅ Only use StringBuffer if you actually need synchronization (very rare in modern designs where threads work with their own copies of data).
🚀 Summary Chart
| Feature | String | StringBuilder | StringBuffer |
|---|---|---|---|
| Mutable? | ❌ No | ✅ Yes | ✅ Yes |
| Thread-Safe? | ✅ Yes | ❌ No | ✅ Yes |
| Performance? | 🐢 Slow (lots of object creation) | 🚀 Fast (no sync) | 🐌 Slow (sync overhead) |
| Typical Use Case | Constants, messages | Processing large texts | Legacy multi-threaded code |