String Immutability
String immutability means that once a String object is created, its value cannot be changed. Any operation that appears to modify a String actually creates a new String object, leaving the original unchanged. This is a must-know interview topic and foundational to understanding String Pool, memory behavior, security, and performance.
What Does Immutability Mean?
- Object state cannot be modified after creation
- Reference may change, but object content does not
- Applies strictly to the String class
String s = "Java";
s.concat(" World");
Result:
• "Java" remains unchanged
• "Java World" is created as a new object
Proof of String Immutability
String s1 = "Java";
String s2 = s1.concat(" World");
System.out.println(s1); // Java
System.out.println(s2); // Java World
✔ Original string is unchanged
✔ New string object is created
Why Strings Are Immutable in Java (Very Important)
1. String Pool Safety
- String literals are stored in the String Constant Pool
- Multiple references may point to the same object
- Immutability prevents unintended changes
String a = "Test";
String b = "Test";
If strings were mutable, changing a would affect b.
2. Security
Strings are widely used for:
- File paths
- Network connections
- Class loading
- User credentials
String path = "/secure/data";
Immutability ensures critical values cannot be altered at runtime.
3. Thread Safety
- Immutable objects are inherently thread-safe
- No synchronization required
- Multiple threads can share the same String safely
4. HashCode Caching (Performance)
- String overrides hashCode()
- Hash value is cached after first calculation
- Enables fast lookup in hash-based collections (HashMap, HashSet)
If strings were mutable, cached hash codes would become invalid.
5. Predictable Behavior
- No side effects
- Easier debugging
- Reliable behavior in APIs and frameworks
How Java Enforces String Immutability
1. String Class Is final
- Cannot be inherited
- Prevents overriding behavior
2. Internal Character Array Is private final
- Internal data cannot be accessed or modified directly
- No setter methods provided
3. Methods Always Return New Objects
s.toUpperCase();
s.replace("a", "o");
s.substring(0, 2);
All return new String objects.
Reference Change vs Object Change (Common Confusion)
String s = "Java";
s = s.concat(" World");
• Original object "Java" still exists
• s now points to a new object
Immutability is about object content, not variable reference.
String Immutability vs StringBuilder Mutability
StringBuilder sb = new StringBuilder("Java");
sb.append(" World");
• Same object is modified
• No new object created
This is why StringBuilder is faster for frequent modifications.
Memory Impact of Immutability
Inefficient Pattern
String s = "";
for (int i = 0; i < 1000; i++) {
s = s + i;
}
• Creates many temporary objects
• High memory usage
Efficient Alternative
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.append(i);
}
String Immutability Examples
1. Basic String Immutability Example
String s = "Java";
s.concat(" Selenium");
System.out.println(s);
Explanation
- concat() creates a new String.
- Original string s remains unchanged.
- Output: Java
2. Correct Way to Modify a String
String s = "Java";
s = s.concat(" Selenium");
System.out.println(s);
Explanation
- Reassignment is required.
- Output: Java Selenium
3. Immutability with replace()
String s = "Java";
s.replace("a", "o");
System.out.println(s);
Explanation
- replace() does not modify original string.
- Output: Java
4. Reassignment After replace()
String s = "Java";
s = s.replace("a", "o");
System.out.println(s);
Explanation
- New string assigned back.
- Output: Jovo
5. Immutability with toUpperCase()
String s = "java";
s.toUpperCase();
System.out.println(s);
Explanation
- Original string unchanged.
- Output: java
6. toUpperCase() with Reassignment
String s = "java";
s = s.toUpperCase();
System.out.println(s);
Explanation
- New object created and assigned.
- Output: JAVA
7. Immutability with substring()
String s = "Automation";
String sub = s.substring(0, 4);
System.out.println(s);
System.out.println(sub);
Explanation
- Original string unchanged.
- Output:
- Automation
- Auto
8. Multiple Operations Still Don’t Change Original String
String s = "Test";
s.concat(" Case").toUpperCase();
System.out.println(s);
Explanation
- All operations create new objects.
- Output: Test
9. String Pool + Immutability
String s1 = "Java";
String s2 = s1.concat(" Selenium");
System.out.println(s1);
System.out.println(s2);
Explanation
- s1 remains in String Pool.
- s2 refers to a new object.
- Output:
- Java
- Java Selenium
10. Reference Change After Modification
String s1 = "Java";
String s2 = s1;
s1 = s1.concat(" Selenium");
System.out.println(s1);
System.out.println(s2);
Explanation
- s2 still points to original string.
- Output:
- Java Selenium
- Java
11. Immutability and Equality (==)
String s1 = "Java";
String s2 = s1.concat("");
System.out.println(s1 == s2);
Explanation
- concat("") returns same reference.
- Output: true
12. Immutability with Non-Empty Concatenation
String s1 = "Java";
String s2 = s1.concat(" ");
System.out.println(s1 == s2);
Explanation
- New object created.
- Output: false
13. Immutability with trim()
String s = " Java ";
s.trim();
System.out.println(s);
Explanation
- Original string unchanged.
- Output: " Java "
14. trim() with Reassignment
String s = " Java ";
s = s.trim();
System.out.println(s);
Explanation
- New trimmed string assigned.
- Output: Java
15. Immutability with Method Chaining
String s = "java selenium";
String result = s.toUpperCase().replace(" ", "_");
System.out.println(s);
System.out.println(result);
Explanation
- Original string unchanged.
- Output:
- java selenium
- JAVA_SELENIUM
16. Why String Is Immutable (Security Example)
String password = "secret";
String ref = password;
password = "changed";
System.out.println(ref);
Explanation
- Original value remains unchanged.
- Helps maintain security and predictability.
17. String vs StringBuilder (Mutability Comparison)
String s = "Java";
s.concat(" Test");
System.out.println(s);
StringBuilder sb = new StringBuilder("Java");
sb.append(" Test");
System.out.println(sb);
Explanation
- String → immutable → unchanged
- StringBuilder → mutable → changed
18. String Immutability in Loops (Performance Issue)
String s = "";
for (int i = 1; i <= 3; i++) {
s = s + i;
}
System.out.println(s);
Explanation
- Multiple String objects created.
- Inefficient due to immutability.
19. Efficient Alternative Using StringBuilder
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 3; i++) {
sb.append(i);
}
System.out.println(sb);
Explanation
- Uses single mutable object.
- Recommended in loops.
20. Interview Summary Example (String Immutability)
String s = "Java";
String t = s;
s = s.concat(" Selenium");
System.out.println(s);
System.out.println(t);
Explanation
- Output:
- Java Selenium
- Java
- Demonstrates:
- Immutability
- Reference behavior
- Very common interview question
Common Misconceptions
- concat() modifies the original string ❌
- String is immutable but reference cannot change ❌
- Immutability means slower performance ❌
- final keyword alone makes an object immutable ❌
Common Beginner Mistakes
- Ignoring immutability and expecting in-place change
- Using String in loops for concatenation
- Confusing reference reassignment with object mutation
- Not understanding memory impact
Interview-Ready Answers
Short Answer
String immutability means a String object cannot be changed once it is created.
Detailed Answer
In Java, String objects are immutable to ensure String Pool safety, thread safety, security, and performance optimizations such as hash code caching. Any modification creates a new String object, leaving the original unchanged.
Key Takeaway
String immutability is a deliberate design choice in Java. It guarantees safety, reliability, and performance, but requires developers to use StringBuilder or StringBuffer for frequent modifications.