What is the difference between String, StringBuilder, and StringBuffer?
String is an immutable class — once created, its value can never change; every modification such as concat() or replace() silently creates a brand-new object on the heap. StringBuilder and StringBuffer are mutable classes that edit an internal resizable character array in place, so repeated edits do not create new String objects.
The difference between the two mutable classes is thread safety: StringBuffer methods are synchronized (thread-safe but slower), while StringBuilder (added in Java 5) is non-synchronized and therefore faster.
Immutability —
Stringliterals are cached in the String pool; modifying one returns a new object and leaves the original untouched, which makes strings safe to share and use asHashMapkeys.Mutability —
StringBuilderandStringBufferprovideappend(),insert(),delete()andreverse(), all of which edit the object in place.Thread safety —
StringBufferis safe when multiple threads touch the same object;StringBuilderis not, but wins on speed in single-threaded code.Performance — concatenating
Stringwith+in a loop creates many temporary objects;StringBuilderavoids that and is the fastest of the three.Automation practice — in Selenium frameworks, use
StringBuilderto build dynamic XPath locators or extent-report messages inside loops, and plainStringfor fixed test data.
Key terms: immutable, mutable, String pool, synchronized, thread-safe,
append(), heap, garbage collection
public class StringComparisonDemo {
public static void main(String[] args) {
// 1. String: immutable — concat() returns a NEW object
String s = "Selenium";
s.concat(" WebDriver"); // result thrown away
System.out.println(s); // Output: Selenium
s = s.concat(" WebDriver"); // must reassign to keep the change
System.out.println(s); // Output: Selenium WebDriver
// 2. StringBuilder: mutable, NOT synchronized (fastest)
StringBuilder xpath = new StringBuilder("//input[@id='");
xpath.append("username").append("']");
System.out.println(xpath); // Output: //input[@id='username']
// 3. StringBuffer: mutable, synchronized (thread-safe)
StringBuffer buffer = new StringBuffer("Test");
buffer.append("NG").insert(0, "Run-");
System.out.println(buffer); // Output: Run-TestNG
}
}The first block proves String immutability: calling concat() alone does not change s because the result is a new object that must be reassigned to be kept. The StringBuilder block shows in-place mutation with chained append() calls — a common SDET pattern for building a dynamic XPath locator without creating intermediate objects.
The StringBuffer block behaves identically to StringBuilder in single-threaded code, but its append() and insert() are synchronized, which is why it is the safe (though slower) choice when multiple threads share one buffer.
Go beyond the one-line definition: state the performance order (StringBuilder fastest, String concatenation in loops slowest) and explain WHY — immutability forces new object creation. Expect follow-ups like "Why is String immutable?", "Which one would you use to build a dynamic XPath in a loop?", and "What happens in the String pool with == vs equals()?".
The classic mistake is claiming StringBuffer is faster than StringBuilder — it is the other way around, because synchronization adds locking overhead.