String Immutability and the String Pool

Strings Never Change

A String object can never be modified. Methods like toUpperCase() or concat() return a new string. Literals are stored once in the string pool and shared.

Example

public class Main {
    public static void main(String[] args) {
        String s = "java";
        s.toUpperCase();                    // result ignored
        System.out.println(s);              // still "java"
        s = s.toUpperCase();                // reassign the variable
        System.out.println(s);

        String a = "hello";
        String b = "hello";                 // same pooled object
        String c = new String("hello");     // new object on the heap
        System.out.println("a == b      : " + (a == b));
        System.out.println("a == c      : " + (a == c));
        System.out.println("a.equals(c) : " + a.equals(c));
        System.out.println("a == c.intern() : " + (a == c.intern()));
    }
}

Output

java
JAVA
a == b      : true
a == c      : false
a.equals(c) : true
a == c.intern() : true

Why Immutable?

  • Safe sharing: the pool can share one object among many variables.
  • Security: file paths, URLs and class names cannot be changed after checks.
  • Thread safety: immutable objects can be shared between threads freely.
  • Hash caching: hashCode is computed once, making strings fast HashMap keys.

Tip: Always compare strings with equals() (or equalsIgnoreCase()), never with ==.