DEV Community

realNameHidden
realNameHidden

Posted on

🧵 Difference Between String, StringBuilder, and StringBuffer in Java

Learn the difference between String, StringBuilder, and StringBuffer in Java with simple explanations, examples, and best practices for writing efficient Java code.


Introduction

Imagine you’re editing a document. You start with a sentence, then add a few words, remove a few others, and rearrange the order. Now imagine that every time you make a small edit, your computer makes a new copy of the entire document — sounds wasteful, right?

That’s exactly what happens in Java if you don’t choose the right string type.

In Java programming, strings are everywhere — from displaying text on the screen to handling user input and constructing URLs. But many beginners get confused between String, StringBuilder, and StringBuffer.

Choosing the right one can make your code faster, more memory-efficient, and thread-safe. Let’s break it down in the simplest possible way.


Core Concepts: String vs StringBuilder vs StringBuffer

🧩 1. String — Immutable and Simple

In Java, a String is immutable, meaning once it’s created, it cannot be changed.

For example:

String s = "Hello";
s = s + " World!";
Enter fullscreen mode Exit fullscreen mode

Here, Java doesn’t modify the original "Hello". Instead, it creates a new String object "Hello World!" and assigns it to s.

This immutability makes strings safe and easy to use, especially for fixed or constant text. However, it’s inefficient when you’re performing many modifications (like concatenating text in a loop).

Use case:

  • When the text doesn’t change frequently (e.g., constants, configuration values, messages).

⚡ 2. StringBuilder — Mutable and Fast (Not Thread-Safe)

StringBuilder was introduced to solve the performance issue of repeatedly creating new String objects.

It allows you to modify the same object instead of creating new ones, making it much faster for tasks like appending or reversing text.

Example:

StringBuilder sb = new StringBuilder("Hello");
sb.append(" World!");
Enter fullscreen mode Exit fullscreen mode

Now, the same object changes its value internally — no new object is created.

But there’s a catch: StringBuilder is not synchronized, meaning it’s not thread-safe. If multiple threads modify the same object simultaneously, unexpected behavior can occur.

Use case:

  • When working in a single-threaded environment and performance is critical (e.g., building large strings or dynamic SQL queries).

🧠 3. StringBuffer — Mutable and Thread-Safe

Before StringBuilder came along, we had StringBuffer. It’s similar to StringBuilder, but all its methods are synchronized, making it thread-safe — meaning multiple threads can safely access it without corrupting data.

However, synchronization adds a small performance cost.

Use case:

  • When working in a multi-threaded environment, and multiple threads might modify the same string data.

🧾 Quick Comparison Table

Feature String StringBuilder StringBuffer
Mutability Immutable Mutable Mutable
Thread-Safe Yes (because immutable) No Yes
Performance Slow for concatenation Fast Moderate
Introduced In Java 1.0 Java 1.5 Java 1.0
Best For Fixed text Single-threaded modification Multi-threaded modification

Code Examples

Example 1: Why String is Slower for Repeated Changes

// Java 21 Example - String concatenation
public class StringPerformanceExample {
    public static void main(String[] args) {
        String text = "Hello";

        // Concatenating multiple times (inefficient)
        for (int i = 0; i < 5; i++) {
            text = text + " Java"; // Creates a new String every time
        }

        System.out.println(text);
    }
}
Enter fullscreen mode Exit fullscreen mode

🧠 Explanation:
Each time you add " Java", a new String object is created and the old one is discarded.
If this happens inside a loop (like when processing large text files), it can slow down your program significantly and increase memory usage.


Example 2: Using StringBuilder for Efficient String Manipulation

// Java 21 Example - Efficient String modification
public class StringBuilderExample {
    public static void main(String[] args) {
        StringBuilder builder = new StringBuilder("Hello");

        // Efficiently appending text
        for (int i = 0; i < 5; i++) {
            builder.append(" Java");
        }

        System.out.println(builder.toString());
    }
}
Enter fullscreen mode Exit fullscreen mode

🧩 Explanation:
Here, StringBuilder modifies the same object repeatedly — no new strings are created.
This approach is much faster and memory-friendly than using regular strings, especially in loops.


Best Practices

  1. Use String for fixed or small text
    Simple tasks like messages, labels, and constants should use immutable String.

  2. Use StringBuilder for heavy string operations
    Ideal for concatenating or modifying strings frequently in single-threaded programs.

  3. Use StringBuffer for thread-safe operations
    Choose this when multiple threads may access and modify the same string data.

  4. Avoid + in loops for concatenation
    Using + repeatedly creates many unnecessary String objects — prefer StringBuilder.append().

  5. Convert wisely
    You can always convert between types:

  • StringBuilder → String using toString()
  • String → StringBuilder using new StringBuilder(str)

Conclusion

Strings might seem simple in Java, but choosing between String, StringBuilder, and StringBuffer can have a huge impact on your application’s performance and reliability.

  • Use String when you don’t need to modify text.
  • Use StringBuilder when building text dynamically in a single-threaded program.
  • Use StringBuffer when working in a multi-threaded environment that requires synchronization.

Mastering these differences will help you write cleaner, faster, and more efficient Java code — a hallmark of a skilled developer.


Top comments (0)