In Java, strings are immutable, meaning their values cannot be changed once created. If you try to modify a string (e.g., using concat() or replace()), a new string object is created instead of altering the original one.
- Strings are stored in a String Pool, allowing reuse of objects and reducing memory overhead.
- Multiple threads can safely share the same string object without synchronization.
- Immutable strings have a consistent hash code, making them reliable for use in collections like HashMap.
Example Demonstrating Immutability
public class GFG {
public static void main(String[] args) {
// Both s1 and s2 refer to the same
// string literal in the String Pool
String s1 = "Hello";
String s2 = "Hello";
// true, both point to the same object in String Pool
System.out.println("s1 == s2: " + (s1 == s2));
// Concatenation creates a new String
// object in heap, s1 now points to it
s1 = s1.concat(" World");
System.out.println("s1: " + s1);
System.out.println("s2: " + s2);
System.out.println("s1 == s2: " + (s1 == s2));
// Creating a string using new keyword stores it in the heap
String s3 = new String("Hello");
// false, because s2 is from String Pool and s3 is from heap
System.out.println("s2 == s3: " + (s2 == s3));
// true, because equals() compares content
System.out.println("s2.equals(s3): " + s2.equals(s3));
}
}
Output
s1 == s2: true s1: Hello World s2: Hello s1 == s2: false s2 == s3: false s2.equals(s3): true
Explanation:
- s1 and s2 initially point to the same object in the String Pool.
- After s1.concat(" World"), a new string object is created for "Hello World".
- s3 is created using new String("Hello") and stored in the heap, separate from the String Pool.
- == checks reference equality: s2 == s3 is false.
- .equals() checks content equality, so s2.equals(s3) is true.
Why Strings Are Designed to Be Immutable
- Memory Efficiency: The String Pool allows multiple references to share the same string object safely.
- Thread Safety: Immutable objects are inherently safe for multi-threaded access.
- Hashcode Reliability: Strings are commonly used as keys in HashMap; immutability ensures the hashcode remains consistent.
- Performance Optimization: JVM can optimize immutable strings, including interning, which saves memory and improves speed.
