intern() returns the canonical copy of a String from the string pool. If the pool already contains an equal String, that object is returned; otherwise this String is added to the pool and returned. After interning, equal Strings can be compared with ==, and duplicate copies can be garbage collected.
Key Points: • All string literals and compile-time constant strings are interned automatically. • Strings created at runtime (new String, concatenation of variables, reading input) are not, until you call intern(). • Since Java 7 the string pool lives in the normal heap, so interned strings can be garbage collected when no longer used. • It can save memory when a program holds millions of copies of a few repeated values, such as country codes or status names. • Interning costs a hash table lookup, so don't intern everything. The G1 collector's -XX:+UseStringDeduplication option is an automatic alternative.
Code Example:
public class InternDemo {
public static void main(String[] args) {
String literal = "PENDING";
String fromInput = new StringBuilder("PEND").append("ING").toString();
System.out.println("Before intern: " + (literal == fromInput));
String interned = fromInput.intern();
System.out.println("After intern: " + (literal == interned));
System.out.println("Content equal all along: " + literal.equals(fromInput));
// Typical memory saving: many equal values read from a file or database
String[] statuses = new String[5];
for (int i = 0; i < statuses.length; i++) {
statuses[i] = new String("PAID").intern(); // all point to one pooled object
}
System.out.println("All share one object: " + (statuses[0] == statuses[4]));
}
}Output:
Before intern: false After intern: true Content equal all along: true All share one object: true
Good to Know: Before Java 7, the pool was in PermGen, a small fixed-size area, so heavy interning could cause "OutOfMemoryError: PermGen space". That is why older articles warn strongly against intern(). In modern Java the risk is much smaller, but the advice to intern only repeated values still stands.
Interview Tip: A concise interview answer is:
"intern() returns the pooled, canonical copy of a String: if an equal String is already in the string pool it returns that one, otherwise it adds this one. Literals are interned automatically, runtime strings aren't. I'd only use it to save memory when a program holds many copies of a few repeated values, and since Java 7 the pool is on the heap, so interned strings can still be garbage collected."
Previous question: How many objects are created by String s = new String("hello")?
Next question: Why is using + to concatenate Strings in a loop slow, and what should you use instead?