What is the String Pool?
Fast recall
Quick revision
Core answer
String.intern() returns the pooled representative equal to a String. In HotSpot, pooled String objects are heap objects, but the specification does not promise one physical table layout.Interview-ready guide
Interview answer
The String pool stores one canonical reference for each interned text value. Java automatically interns string literals and string-valued constant expressions, so repeated literals can share the same String object.
For example, two uses of the literal "java" normally point to the same pooled String. new String("java") creates a different object with the same characters, so equals returns true but == returns false. Calling intern() on that new String returns the pooled reference.
Runtime-created text is not automatically the pooled reference just because its characters match a literal. A concatenation involving variables produces a normal String unless the program explicitly interns it. Application code should still use equals for text comparison because == checks object identity.
The Java API defines the canonical behaviour, not one required table layout or physical address. In current HotSpot, interned String objects live in the managed heap; PermGen explanations describe older JVMs. Interning a small repeated vocabulary can help, but interning unbounded user data is not a safe general-purpose cache.
What is the String Pool
Direct Answer
The String pool is the JVM's canonical set of interned String values. String literals and string-valued constant expressions are interned, and String.intern() returns the pooled representative equal to a String. In HotSpot, pooled String objects are heap objects, but the specification does not promise one physical table layout.
Deep Dive & Architecture
Automatic string interning
A literal such as "java" is interned. The compiler can also fold the constant expression "ja" + "va", so it denotes the same interned value. If one operand is a runtime variable, concatenation happens during execution and the resulting String is not guaranteed to be the pooled representative even when its characters match the literal.
new String("java") deliberately asks for a distinct String object initialized from the literal's value. Its equals result matches the literal because their characters match, while == observes different references. Calling intern() returns the canonical pooled reference. This is a teaching example for identity, not a reason to compare application text with ==.
When string interning is appropriate
Interning can reduce duplicate identities for a small, repeated vocabulary, but enums or domain value objects often express fixed choices more clearly. Interning user IDs, URLs, or other unbounded external values turns input cardinality into pool lookup and memory pressure. Measure a real benefit before adding it as a cache.
API guarantees and HotSpot implementation details
The Java API specifies canonical equality behaviour, not a public hash-table design or permanent address. Current HotSpot keeps pooled String objects in the managed heap; older PermGen explanations are historical. Pooling also does not cause immutability—String is immutable whether pooled, newly constructed, or returned by a runtime operation.
Code Example
class StringPool {
public static void main(String[] args) {
String firstLiteral = "java";
String secondLiteral = "ja" + "va";
String created = new String("java");
System.out.println(firstLiteral == secondLiteral);
System.out.println(firstLiteral == created);
System.out.println(firstLiteral.equals(created));
System.out.println(firstLiteral == created.intern());
}
}
Check your understanding
Answer these without looking back at the article.
- What is the difference between equals and == for String?
- Is runtime string concatenation automatically interned?
- Why can interning unbounded external values be harmful?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.