Course topics

By WebNest Studio Engineering Team

Java - Core Tutorial

Why Strings Are Immutable in Java

In Java, once a String object is created, its contents can never change. Methods that appear to modify a String, such as concat() or replace(), actually return a brand-new String object and leave the original untouched. This is not an accident or a limitation — it is a deliberate design decision with several concrete benefits.

Why it matters

Immutability is the reason Strings can be shared safely between threads, cached in a pool, and trusted as map keys and as arguments to security-sensitive code. It also explains the behaviour that trips people up: passing a String to a method can never change the caller's String. "Why is String immutable?" is one of the most frequently asked Java interview questions.

Security

Many sensitive operations take a String as a parameter: opening a file path, connecting to a network host, loading a class by name, or checking a username. If String were mutable, code could validate a String (for example, checking that a file path is safe) and then have another part of the program — or malicious code — change the contents of that same String object afterward, bypassing the validation entirely. Immutability guarantees that once a String has been checked, it cannot be altered underneath the code that checked it.

The String Pool and Thread-Safety

Java maintains a special memory area called the String pool (part of the heap) where String literals are cached and reused. When you write String a = "hello"; and String b = "hello";, both variables point to the exact same object in the pool, saving memory. This sharing is only safe because Strings cannot change — if one reference could modify the shared object, every other reference to that literal would unexpectedly change too. Immutability also makes String inherently thread-safe: multiple threads can read the same String concurrently with no risk of one thread seeing a partially modified value, and no synchronization is needed.

Safe Use as HashMap Keys

String's hashCode() is computed once and cached internally, because the value can never change after construction. This makes String an excellent, efficient key type for HashMap and HashSet — the hash code is guaranteed to stay valid for the object's entire lifetime, which would not be true for a mutable key (a mutable key that changes after being inserted into a HashMap can become permanently unreachable in that map).

What Actually Happens with s = s + "x"

When you write s = s + "x";, Java does not modify the memory that s originally pointed to. Instead, it creates a brand-new String object containing the concatenated result and reassigns the reference s to point at that new object. The original String object still exists unchanged in memory (and will eventually be garbage collected if nothing else references it) — only the reference variable was updated to point elsewhere.

Example

Concatenation creates a new object instead of mutating the original

Java
public class StringImmutabilityDemo {
    public static void main(String[] args) {
        String s1 = "hello";
        String s2 = s1;

        s1 = s1 + " world"; // creates a new String object, does not modify the original

        System.out.println(s1);
        System.out.println(s2);
        System.out.println(s1 == s2);
    }
}
Output
hello world
hello
false

Common Mistakes

  • Believing that methods like replace() or toUpperCase() modify the original String in place — they always return a new String that must be captured (e.g. "s = s.toUpperCase();").
  • Concatenating Strings heavily inside a loop with "+", not realizing each concatenation creates a new object, which wastes memory and time — StringBuilder should be used instead for repeated concatenation.
  • Assuming two Strings with the same text created with "new String(...)" are the same object as a literal — use .equals() for content comparison, not == , since == compares references.
  • Forgetting that String immutability is exactly what makes the String pool and safe HashMap key usage possible in the first place.

Exercise

The method below is supposed to add an exclamation mark to the message, but the program prints Hello. Change the method and the call so that it prints Hello!.

Java · starter code
public class AddSuffix {

    static void addSuffix(String s) {
        s = s + "!";
    }

    public static void main(String[] args) {
        String message = "Hello";
        addSuffix(message);
        System.out.println(message);
    }
}
Show hints
  • s + "!" creates a new String. Assigning it to the parameter s does not affect the variable in main.
  • Return the new String from the method and assign the result back to message.
Show solution
Java · solution
public class AddSuffix {

    static String addSuffix(String s) {
        return s + "!";
    }

    public static void main(String[] args) {
        String message = "Hello";
        message = addSuffix(message);
        System.out.println(message); // Hello!
    }
}

Quick quiz

1. Which of these is a direct benefit of Strings being immutable?

  • A. Strings use less CPU to create
  • B. Strings never need garbage collection
  • C. Strings can be modified in place
  • D. A String can be shared between threads without synchronization
Show answer

D. Because no thread can change a String, sharing one is always safe. That also makes the string pool possible.

2. After String s = "ab"; s.concat("c");, what is the value of s?

  • A. ab
  • B. abc
  • C. c
  • D. null
Show answer

A. concat() returns a new String. Since the result is not assigned, s still refers to "ab".

3. Why is the String class declared final?

  • A. To make it faster to load
  • B. So that no subclass can override its behaviour and break immutability
  • C. So that String variables cannot be reassigned
  • D. Because it has no constructors
Show answer

B. If String could be subclassed, a subclass could add mutable state or change methods, and code that relies on Strings never changing would no longer be safe.

Interview questions

Why are Strings immutable in Java?

Show answer

Four reasons are usually given. The string pool depends on it: many variables share one object, so no one may change it. Security: file paths, URLs and class names are passed as Strings and must not change after being validated. Thread safety: an immutable object can be shared freely. And hashing: the hash code can be computed once and cached, which makes Strings efficient and reliable as HashMap keys.

Why is a char[] often recommended over a String for storing a password?

Show answer

A String cannot be cleared: it stays in memory until the garbage collector removes it, and a literal can live in the pool for the life of the program, so it may appear in a heap dump. A char[] can be overwritten with zeros as soon as you have finished with it. It is also harder to print by accident, since printing an array does not show its contents.

Key Points to Remember

  • String immutability prevents tampering with validated data used in security-sensitive operations like file paths and class loading.
  • The String pool can safely share literal objects only because Strings can never be modified after creation.
  • Immutable Strings are inherently thread-safe and make efficient, reliable HashMap/HashSet keys via a cached hash code.
  • Operations like s = s + "x" create a new String object and reassign the reference; they never mutate the original object.

Practice in the playground

Write and run your own code for this topic, or start from the exercise or an example. Runs plain Java 17. Frameworks such as Spring, and databases, are not available here. Your code for each topic is kept in this browser.

Run the examples

Change an input, predict the result, then compare it with the output. Explain why the result changes.

WebNest Studio

Written by

WebNest Studio Engineering Team

Practical lessons from developers working with Java, Python, React, databases and production systems.

Led by Vansh Duggal, Founder, WebNest Studio · Full-stack & software engineering