Understanding Java String.intern() Behavior and Memory Address Comparisons
This article explains why the results of comparing strings with the == operator differ when using String.intern() in Java, illustrating the behavior with code examples, bytecode analysis, and JVM constant pool details to clarify true versus false outcomes.
The article begins by presenting a Java test class that creates several strings using new StringBuilder(...).toString() and prints the results of intern() and == comparisons. The expected console output is shown:
helloWorld
true
java
false
hello
falseIt then asks why these results appear and explains that the == operator compares object references, so understanding the memory addresses of str1 , str1.intern() , str2 , str2.intern() , str3 , and str3.intern() is essential.
Since the JVM does not expose direct address APIs, the article suggests using System.identityHashCode() as a proxy to differentiate objects. Different hash codes guarantee different objects, while identical hash codes do not guarantee sameness.
A second code example ( GCTest ) demonstrates the use of System.identityHashCode() to show that the newly created "java" string and the one already present in the runtime constant pool have different addresses, resulting in a false comparison, whereas "helloWorld" becomes the same object after intern() , yielding true .
public class GCTest {
public static void main(String[] args) {
String str1 = new StringBuilder("ja").append("va").toString();
String str2 = str1.intern();
System.out.println(str1 == str2);
System.out.println(System.identityHashCode(str1));
System.out.println(System.identityHashCode(str2));
String str3 = new StringBuilder("hello").append("world").toString();
String str4 = str3.intern();
System.out.println(str3 == str4);
System.out.println(System.identityHashCode(str3));
System.out.println(System.identityHashCode(str4));
}
}The article then analyses the bytecode of the original TestDemo class, pointing out that literals like "hello", "World", "ja", and "va" are already in the constant pool, while the literal "java" is pre‑loaded by the JVM during class initialization (via System.initializeSystemClass() and sun.misc.Version.init() ), which explains why its intern() call returns a different object.
Finally, the article summarizes that strings already present in the runtime constant pool (such as "java") will cause str == str.intern() to be false , whereas a newly created string that is not yet in the pool (like "helloWorld") will be added by intern() and thus the comparison yields true . The same reasoning applies to other examples like the plain "hello" string, which remains a distinct object after intern() , resulting in false .
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.