Why String Is Immutable in Java

A String in Java is a widely used object that stores a sequence of characters.
One of the most important properties of the String class in Java is that it is immutable.

What Is an Immutable Object?

An immutable object is an object whose state (data) cannot be changed after it is created.

  • Once a string is created, its content cannot be altered.
  • Any modification creates a new string object.

✔️ Example of Immutable Behavior

public class ImmutableStringExample {
    public static void main(String[] args) {
        String str = "Java";
        str.concat("Knowledge Base");  // This does NOT modify the original str
        
        System.out.println(str);  // Output: Java 
    }
}

👉 To get the modified string, you must explicitly assign it:

str = str.concat("Knowledge Base");
System.out.println(str);  // Output: Java Knowledge Base

Why Is String Immutable in Java?

1️⃣ String Pool Benefit

When dealing with strings in Java, a key concept that improves performance and memory management is the String Constant Pool (or String Pool).

What Is the String Pool?

  • The String Pool is a special memory region in the Java heap.
  • It stores unique string literals.
  • Every time a string literal is created using double quotes (" "), the JVM checks the pool first:
    • If the string already exists → It reuses the same reference.
    • If the string doesn’t exist → It adds the string to the pool.

Example: String Pool Behavior (literals)

public class StringPoolExample {
    public static void main(String[] args) {
        String str1 = "Java Knowledge Base";
        String str2 = "Java Knowledge Base";
        System.out.println(str1 == str2);  // Output: true
    }
}

👉 Explanation:

  • Both str1 and str2 point to the same object in the String Pool.
  • The == operator returns true because both variables reference the same memory address.

✅ Example: Using new Keyword

public class StringPoolExample2 {
    public static void main(String[] args) {
        String str1 = "Java Knowledge Base";
        String str3 = new String("Java Knowledge Base");

        System.out.println(str1 == str3);  // Output: false
    }
}

👉 Explanation:

  • str1 refers to the pooled string object.
  • str3 refers to a new object in the heap memory.
  • Therefore, str1 == str3 is false.

2️⃣ Security

Key Use Cases Where Strings Play a Critical Role:

  • Database connection URLs
  • Usernames and passwords
  • Network connections

If strings were mutable, any malicious code running in the same application or process could modify the string content unexpectedly, leading to potential security breaches.

Example: Password in String (Immutable)
public class SecurityExample {
    public static void main(String[] args) {
        String password = "SuperSecret123";  // Stored in String Constant Pool

        // Imagine some malicious code tries to change the password
        // Since String is immutable, the original value remains unchanged
        password.concat("MaliciousPart");  // Creates a new String object, does not alter original

        System.out.println("Password: " + password);  // Output: SuperSecret123
    }
}

👉 Explanation:

  • The call to password.concat("MaliciousPart") creates a new string but does NOT modify the original password.
  • This behavior protects sensitive data from being tampered with by malicious code.
Contrast: Mutable Example (Hypothetical MutableString)
class MutableString {
    String value;

    MutableString(String value) {
        this.value = value;
    }

    void setValue(String newValue) {
        this.value = newValue;
    }
}

public class MutableExample {
    public static void main(String[] args) {
        MutableString password = new MutableString("SuperSecret123");

        // Malicious code can change the value
        password.setValue("HackedPassword!");

        System.out.println("Password: " + password.value);  // Output: HackedPassword!
    }
}

👉 Why This Is Dangerous:

  • Sensitive data like passwords can be altered at runtime.
  • Could allow attackers to inject values or manipulate security-critical variables.

3️⃣ Hashcode Synchronization

One of the important reasons why Java’s String class is immutable is to ensure hashcode consistency.

  • The hashCode() method for a string is computed only once and cached for future use.
  • Immutability guarantees that the string’s hashcode remains constant throughout its lifetime, which is essential for reliably storing and retrieving strings in hash-based collections like HashMap.
What Is hashCode()?
  • The hashCode() method returns an integer value representing the content of the object.
  • It is heavily used in hash-based collections like:
    • HashMap
    • HashSet
    • Hashtable

Why Hashcode Consistency Matters

  • Collections like HashMap store key-value pairs in buckets based on the hashcode of the key.
  • If the content of a key (a string, in this case) were to change after being added to a map:
    • The hashcode would change.
    • The object would be stored in the wrong bucket.
    • Retrieving the key later would fail.

Example:

public class HashcodeExample {
    public static void main(String[] args) {
        String str = "Java";
        
        // First computation of hashcode
        int hash1 = str.hashCode();
        
        // Second computation of hashcode
        int hash2 = str.hashCode();
        
        System.out.println("Hash1: " + hash1);
        System.out.println("Hash2: " + hash2);
        System.out.println("Hashes are equal: " + (hash1 == hash2));  // Output: true
    }
}

👉 Why This Works:

  • Subsequent calls return the same value without recomputation.
  • The string content "Java" cannot change because of immutability.
  • The JVM computes the hashcode only once and caches it.

4️⃣ Thread Safety

Immutable strings are inherently thread-safe:

  • Multiple threads can share the same String object safely without the need for explicit synchronization.
  • This prevents race conditions or unexpected behavior in a multithreaded environment.
  • No risk of data inconsistency or corruption.

5️⃣ Performance Optimization

✔️ How Does Immutability Improve Performance?
  • Because strings are immutable, they can be safely reused from the string pool.
  • Avoids unnecessary object creation when using literals.

Summary Table: Why Strings Are Immutable

ReasonBenefit
String PoolMemory optimization & reuse
SecurityImmutable sensitive data
Hashcode ConsistencyReliable for HashMap & HashSet
Thread SafetySafe concurrent access
PerformanceAvoid repeated object creation

Java developer with 9+ years of IT experience, sharing tutorials and tips to help learners master Java programming.

Leave a Reply

Your email address will not be published. Required fields are marked *