Hiprup

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.

  • ImmutabilityString literals 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 as HashMap keys.

  • MutabilityStringBuilder and StringBuffer provide append(), insert(), delete() and reverse(), all of which edit the object in place.

  • Thread safetyStringBuffer is safe when multiple threads touch the same object; StringBuilder is not, but wins on speed in single-threaded code.

  • Performance — concatenating String with + in a loop creates many temporary objects; StringBuilder avoids that and is the fastest of the three.

  • Automation practice — in Selenium frameworks, use StringBuilder to build dynamic XPath locators or extent-report messages inside loops, and plain String for 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.