Secret of String Why String is Immutable in Java
Last updated: September 2026 — refreshed with modern Java notes, code examples, and interview Q&A.
"Why is String immutable in Java?" is one of those interview questions you will face at every level — fresher, senior, even architect rounds. It's evergreen because the answer touches memory management, security, concurrency, and collections all at once. Let's break it down properly.
How Java enforces String immutability
Before the why, understand the how. String is immutable by construction:
public final class String implements java.io.Serializable,
Comparable<String>, CharSequence {
private final byte[] value; // char[] before Java 9 (compact strings)
private final byte coder;
private int hash; // cached hashCode
...
}
Three things lock it down:
finalclass — nobody can subclass String and sneak in mutable behavior.private finalinternal array — the characters can't be reassigned or reached from outside, and the constructor defensively copies the array it receives.- No mutator methods — every "modifying" method (
substring(),concat(),replace()) returns a new String instead of changing the original.
String s = "Pepsi";
s.concat(" Cola"); // returns a NEW string — s is unchanged
System.out.println(s); // still "Pepsi"
s = s.concat(" Cola"); // only reassignment changes what s points to
The 5 reasons String is immutable
1. String constant pool
The JVM keeps a special area in heap memory — the string constant pool — holding exactly one copy of each distinct string literal. When you write:
String a = "Pepsi"; String b = "Pepsi"; // reuses the pooled object — no new allocation
Both variables point to the same object. This sharing is only safe because the object can never change. If a could mutate the pooled "Pepsi" into "Vat69", b would silently change too. Sharing without immutability is a bug factory.
2. Security
Strings carry the most sensitive parameters in a program — usernames, passwords, URLs, database connection strings, file paths. Consider this:
Connection conn = DriverManager.getConnection(url, username, password);
If String were mutable, another thread (or malicious code holding a reference) could alter the password after authentication but before use. Immutability closes that window completely.
3. Thread safety without synchronization
Immutable objects are inherently thread-safe — no thread can change shared state, so no locks are needed. You can freely share String instances across threads with zero synchronization overhead. (This is also why designing your own immutable classes is a classic interview follow-up.)
4. Safe class loading
The class loader takes class names as Strings. If Strings were mutable, code could alter a class name between the security check and the actual load — loading a rogue class under a trusted name. Immutability makes the checked name and the loaded name provably identical.
5. Hashing performance
String is the most common HashMap key in existence. Because it's immutable, its hashCode() is computed once and cached in the hash field — no recomputation on every map lookup. (See why hashCode() matters and why equals() matters.) A mutable key whose hash changed after insertion would make entries unfindable — the map would silently corrupt.
What would break if String were mutable?
Interviewers love this inversion. Short answer: everything above — the constant pool would become unsafe, HashMap keys would corrupt, the class loader would be exploitable, and every shared string would need synchronization. It's a good one-line summary if you're pressed for time.
String vs StringBuilder vs StringBuffer
The inevitable follow-up: "So how do I build strings efficiently?"
- String — immutable. Use for fixed text and keys.
- StringBuilder — mutable, not synchronized. Use for building strings in a single thread (loops, concatenation).
- StringBuffer — mutable and synchronized. Use only when shared across threads; otherwise StringBuilder is faster.
// Don't do this in a loop — creates a new String every iteration String result = ""; for (String word : words) result += word; // Do this instead StringBuilder sb = new StringBuilder(); for (String word : words) sb.append(word); String result = sb.toString();
Interview rapid-fire
- Why is String declared final? — So no subclass can override behavior and break the immutability contract.
- Difference between
"abc"andnew String("abc")? — The literal reuses the pooled instance;newalways creates a fresh heap object. - Is String thread-safe? — Yes, by immutability — no synchronization needed.
- Why is String a good HashMap key? — Immutable plus cached hashCode: the hash can't change after insertion.
- How would you make your own immutable class? — Final class, private final fields, no setters, defensive copies of mutable inputs. (Full walkthrough in this post.)
Related reading
- What is the String constant pool?
- How to create an immutable class in Java
- Comparable vs Comparator — another evergreen interview classic
- Core Java interview questions for freshers
very nice article on String.....Hats off sir, this site is really a helping hand for students like me
ReplyDelete