String Intern Method in Java
Literals go into the String pool automatically, but text built while the program runs, from user input, a file, or StringBuilder, does not. The intern() method lets you ask for the pooled version of any string: "if this text is already in the pool, give me that object; if not, add mine and give it back." It's a small method with one clear job, and it explains a lot about how the pool works.
Pooling a Runtime String
public class Intern {
public static void main(String[] args) {
String fromUser = new StringBuilder("Pu").append("ne").toString();
String literal = "Pune";
System.out.println(fromUser == literal);
String pooled = fromUser.intern();
System.out.println(pooled == literal);
System.out.println(fromUser == pooled);
}
}false
true
falseHow it works
fromUseris built at runtime byStringBuilder, so it's a separate object, not in the pool.fromUser == literalisfalse, even though the text is the same.fromUser.intern()looks up"Pune"in the pool. The literal already put it there, sointern()returns that pooled object:pooled == literalistrue.intern()doesn't changefromUser(strings never change); it returns a different reference.
When Is It Useful?
Imagine reading a million rows from a file where a "city" column has only 50 different values. Without interning, you'd hold a million separate String objects; with city = city.intern();, you'd hold 50, all shared.
| Good fit | Poor fit |
|---|---|
| Huge numbers of strings with few distinct values | Strings that are mostly unique, like names or ids |
| Long-lived data loaded once | Short-lived values in a request |
| Memory is tight | Ordinary application code |
Common Mistakes
Interning everything. It adds a lookup to every string and fills the table with values that are never reused.
Expecting intern() to change the original string. Use its return value.
Comparing with == after interning "most" strings. One un-interned string breaks the comparison silently.
Under the Hood
The pool is a hash table inside the JVM. Since Java 7 it stores ordinary heap objects, so interned strings that nothing refers to any more are garbage collected. The table's size can be tuned with -XX:StringTableSize, and jcmd <pid> VM.stringtable prints statistics about it on a running program. Garbage collectors such as G1 can also remove duplicate string contents automatically with -XX:+UseStringDeduplication, which often saves memory without any intern() calls in your code.
Interview Corner
What does String.intern() do?
It returns a canonical, pooled representation of the string. If the pool already contains a string equal to this one, that pooled object is returned; otherwise this string is added to the pool and returned. Literals are interned automatically, so new String("a").intern() == "a" is true.
Practice
- Easy: Build
"Java"from"Ja"and"va"withStringBuilder, then show the result of==with the literal"Java"before and afterintern(). - Harder: Create an array of 100,000 strings by repeating ten city names built with
new String(...). Intern each one, and use==on two elements with the same city to show they're now the same object.
Key Takeaways
Was this tutorial helpful?