Difference Between String, StringBuffer, and StringBuilder in Java

Difference Between String, StringBuffer, and StringBuilder in Java


If you are starting Java and keep hearing about String, StringBuffer, and StringBuilder, this guide is for you. We will explain the difference between these three, when to use each, and how they behave with simple, clear examples. By the end, you will confidently choose the right one in your code. This beginner-friendly tutorial focuses on String vs StringBuffer vs StringBuilder in Java for beginners and also answers common questions students ask.

Quick takeaway for beginners: String vs StringBuffer vs StringBuilder in Java

  • String: Immutable, pooled, and safe to share. Best for constants, messages, and map keys.
  • StringBuilder: Mutable and fastest for single-threaded work. Best for building text in loops or local scopes.
  • StringBuffer: Mutable and thread-safe. Best when a builder is shared and modified across threads.

Why does Java have three different string types?

String vs StringBuffer vs StringBuilder in Java for beginners: immutability vs mutability visual
How Java String creates new objects while StringBuffer/StringBuilder modify the same data in place

In Java, text is very common, but different situations need different behaviors:

  • String is simple and safe to share because it is immutable (cannot change after creation).
  • StringBuffer is mutable (can change) and thread-safe (safe to use from multiple threads).
  • StringBuilder is mutable but not thread-safe, so it is usually faster for single-threaded code.

Understanding mutable vs immutable strings in Java helps you write code that is both correct and efficient.

What is String in Java?

String vs StringBuffer vs StringBuilder in Java for beginners: thread safety and performance graphic
Why StringBuffer uses locks for threads and StringBuilder runs faster in single-threaded code

A String represents an immutable sequence of characters. Once created, its value cannot change. Because of immutability, Strings are safe to share between threads and can be used as keys in maps reliably. Java also uses a String pool to reuse common string literals, saving memory.

Syntax and simple example

Code
class="cd-keyword cd-access">public class StringIntro {
    class="cd-keyword cd-access">public static void main(String[] args) {
        String a = "Java";              // from string pool
        String b = "Java";              // reused from pool
        String c = new String("Java");  // new object on the heap

        System.out.println(a == b);     // true: both reference the same pooled object
        System.out.println(a == c);     // false: c is a distinct object
        System.out.println(a.equals(c));// true: same content

        String s = "Hello";
        s.concat(" World");             // returns a new String, original s unchanged
        System.out.println(s);          // prints ___CDPHSTR5___

        String t = s + " World";        // creates a new String
        System.out.println(t);          // prints ___CDPHSTR7___
    }
}
Output
true
false
true
Hello
Hello World

Why use String?

  • Good for constants, messages, and values that do not change.
  • Safe to share across threads.
  • Works well as keys in collections because content cannot change after hashing.

Common mistake with String

  • Using String concatenation (+) inside loops for large builds. This creates many short-lived objects and can be slow. Prefer StringBuilder for building large text in loops.

What is StringBuffer in Java?

StringBuffer is a mutable sequence of characters. You can append, insert, delete, and modify its content without creating new objects. It is synchronized, which makes it thread-safe but typically slower than StringBuilder in single-threaded code.

Syntax and simple example

Code
class="cd-keyword cd-access">public class StringBufferIntro {
    class="cd-keyword cd-access">public static void main(String[] args) {
        StringBuffer sb = new StringBuffer("Java");
        sb.append(" Programming");   // mutates the same object
        sb.insert(0, "Learn ");      // insert at the beginning
        sb.delete(5, 6);             // remove the space after ___CDPHSTR3___
        sb.reverse();                // reverse characters
        System.out.println(sb.toString());
    }
}
Output
gnimmargorPavaJnraeL

When to use StringBuffer?

  • When multiple threads modify the same text builder instance.
  • When you need built-in thread safety without external synchronization.

What is StringBuilder in Java?

StringBuilder is also a mutable sequence of characters like StringBuffer but is not synchronized. That means it is not thread-safe, but typically faster in single-threaded or local-scope use.

Syntax and simple example

Code
class="cd-keyword cd-access">public class StringBuilderIntro {
    class="cd-keyword cd-access">public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        sb.append("Hello");
        sb.append(' ');
        sb.append("World");
        sb.replace(6, 11, "Java");
        System.out.println(sb.toString()); // ___CDPHSTR4___
    }
}
Output
Hello Java

Mutable vs Immutable Strings in Java

  • Immutable (String): Any change creates a new object. Safe, predictable, and shareable. Good for constants and keys.
  • Mutable (StringBuffer/StringBuilder): Changes happen in place. Efficient for building or modifying text repeatedly.

String vs StringBuffer vs StringBuilder: Key differences

Feature String StringBuffer StringBuilder
Mutability Immutable Mutable Mutable
Thread safety Safe by design (cannot change) Thread-safe (synchronized) Not thread-safe
Typical performance Slow for repeated concatenation Slower than StringBuilder (sync overhead) Faster for single-threaded builds
Use cases Constants, messages, map keys Shared builders across threads Local builders in loops, parsing, formatting
Introduced Java 1.0 Java 1.0 Java 5
Package java.lang java.lang java.lang
Common methods length, charAt, substring, concat append, insert, delete, reverse append, insert, delete, reverse

How to choose between String, StringBuffer, and StringBuilder in Java

  • Use String for values that don’t change or when you need thread-safe sharing without synchronization.
  • Use StringBuilder when building or modifying text in a single thread, especially inside loops.
  • Use StringBuffer when multiple threads modify the same builder instance and you need built-in thread safety.

When does thread safety matter for StringBuffer or StringBuilder?

  • If a builder is shared across threads and modified concurrently, choose StringBuffer or add your own synchronization around StringBuilder.
  • If each thread has its own builder (no sharing), StringBuilder is fine.

Visual selection flow for beginners

Choose the right type (beginner flow)
Start: What will you do with the text?
Will the value change repeatedly (e.g., inside a loop)?

No → Use String
Reasons: immutable, pooled, safe for map keys.
Yes → Next question

Is the builder shared and modified across threads?

Yes → Use StringBuffer
Reason: synchronized (thread-safe).
No → Use StringBuilder
Reason: faster in single-threaded code.

Special note: For identifiers, config, or map keys, prefer String even if created via a builder.

String vs StringBuilder performance in Java for beginners

This example times repeated concatenation with String and StringBuilder. Exact numbers vary by computer and JVM, but you should see that StringBuilder is usually faster for many appends.

Relative, conceptual bars (longer ≈ better/faster). Not measured.
Build speed for heavy concatenation (single thread)
StringBuilder

StringBuffer

String

Built-in thread-safety for shared, mutable builders
StringBuffer

StringBuilder

Note: String is immutable and not used as a shared mutable builder, so it is not shown in the thread-safety row.
Code
class="cd-keyword cd-access">public class PerformanceDemo {
    class="cd-keyword cd-access">public static void main(String[] args) {
        int n = 50_000;

        long t1 = System.nanoTime();
        String s = "";
        for (int i = 0; i < n; i++) {
            s += i; // creates many temporary Strings
        }
        long t2 = System.nanoTime();

        long t3 = System.nanoTime();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < n; i++) {
            sb.append(i);
        }
        String result = sb.toString();
        long t4 = System.nanoTime();

        System.out.println("String time (ms): " + (t2 - t1) / 1_000_000.0);
        System.out.println("StringBuilder time (ms): " + (t4 - t3) / 1_000_000.0);
        System.out.println("Sizes: " + s.length() + " vs " + result.length());
    }
}
Output
String time (ms): 150.7
StringBuilder time (ms): 4.9
Sizes: 238889 vs 238889

Note: Times above are only an example; your results will differ, but StringBuilder should generally be faster.

Difference between String and StringBuffer in Java with example

Code
class="cd-keyword cd-access">public class StringVsStringBufferExample {
    class="cd-keyword cd-access">public static void main(String[] args) {
        // String is immutable
        String s = "Hi";
        modifyString(s);
        System.out.println("String after modify: " + s); // unchanged

        // StringBuffer is mutable
        StringBuffer sb = new StringBuffer("Hi");
        modifyStringBuffer(sb);
        System.out.println("StringBuffer after modify: " + sb); // changed
    }

    static void modifyString(String x) {
        x = x + " there"; // new object created, original not affected
    }

    static void modifyStringBuffer(StringBuffer x) {
        x.append(" there"); // modifies the same object
    }
}
Output
String after modify: Hi
StringBuffer after modify: Hi there

Difference between StringBuffer and StringBuilder in Java with example

Both are mutable and have similar APIs. The key difference is synchronization (thread safety). Here is the same operation using each:

Code
class="cd-keyword cd-access">public class BufferBuilderExample {
    class="cd-keyword cd-access">public static void main(String[] args) {
        StringBuffer sbuf = new StringBuffer("Start");
        sbuf.append(" -> ").append("Buffer");
        System.out.println(sbuf.toString());

        StringBuilder sbld = new StringBuilder("Start");
        sbld.append(" -> ").append("Builder");
        System.out.println(sbld.toString());
    }
}
Output
Start -> Buffer
Start -> Builder

In single-threaded code, StringBuilder often runs faster because it avoids synchronization overhead.

Common mistakes (and how to fix them)

  • Using String for heavy concatenation in loops: Switch to StringBuilder.
  • Assuming StringBuffer is always faster because it is mutable: In single-threaded code, StringBuilder is typically faster.
  • Sharing StringBuilder across threads without synchronization: Either use StringBuffer or protect your StringBuilder with external synchronization.
  • Forgetting that String is immutable: Methods like concat, replace, or toUpperCase return new strings. Assign the result: s = s.toUpperCase();

People also ask: Quick answers

What is the main difference between String and StringBuffer in Java?

String is immutable (cannot change), while StringBuffer is mutable and thread-safe. Modifying a String creates a new object; modifying a StringBuffer changes the same object.

Is StringBuilder faster than StringBuffer in Java?

Usually yes in single-threaded code, because StringBuilder is not synchronized and avoids the overhead of thread-safety checks.

Why is String immutable in Java?

Immutability improves security, caching (string pool), performance in some cases, and safe sharing across threads. It also allows reliable use as keys in hash-based collections.

Which should I use in Java: String, StringBuffer, or StringBuilder?

  • Use String for values that don’t change.
  • Use StringBuilder for building text in one thread.
  • Use StringBuffer if multiple threads modify the same builder.

When does thread safety matter for StringBuffer or StringBuilder?

It matters when multiple threads share and modify the same builder instance. If there is no sharing, use StringBuilder.

Quick checklist: How to choose

  1. Is the text constant or rarely modified? Use String.
  2. Are you building/concatenating text in a loop? Use StringBuilder.
  3. Will multiple threads modify the same builder? Use StringBuffer or synchronize around StringBuilder.
  4. Do you need a stable value for map keys? Use String.

Practice exercises

  • Rewrite a loop that builds CSV data using String concatenation to use StringBuilder. Measure time using System.nanoTime().
  • Create a method that accepts a StringBuffer and appends a suffix. Call it from two threads and observe safe behavior. Then try with StringBuilder and see why you need synchronization.

Learn more Java basics

Continue your Java journey with more beginner-friendly tutorials at CodDesire Java Tutorials.

Sources / Further reading

That’s the complete beginner-friendly guide to String vs StringBuffer vs StringBuilder in Java for beginners. With the concepts, examples, and performance tips above, you can now decide confidently which type to use and why.

Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted