Why == Fails but equals Works: Java String Comparison Explained
This article explains how Java’s == operator compares object references while the String class’s equals method compares actual character values, covering JVM memory layout, literal pooling, code implementation, and practical examples that clarify common interview questions.
Conceptual Difference
In Java, the == operator checks whether two variables reference the exact same memory location, whereas String.equals() checks whether the character sequences stored in those objects are identical.
JVM Memory Allocation
Java memory is divided into heap and stack. Using new creates an object on the heap and stores a reference to it on the stack. String str = new String("程序新视界"); Here, the actual String object resides in the heap, while the variable str holds a stack reference.
How String Implements equals
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}The first if uses == to compare references. The subsequent block casts the argument to String and compares each character in the internal char[] arrays, returning true only when all characters match.
Object’s Default equals
public boolean equals(Object obj) {
return (this == obj);
}Because Object.equals() also compares references, the statement "== compares references, equals compares values" is only true for classes that override equals, such as String.
String Literals vs. new Instances
String literals are stored in the JVM’s constant pool. When a literal is used, the JVM first checks the pool; if an identical value exists, the same object reference is returned. Thus, literals with the same content share one object.
Creating a String with new always allocates a fresh object on the heap.
Example Verification
String x = "程序新视界";
String y = "程序新视界";
String z = new String("程序新视界");
System.out.println(x == y); // true
System.out.println(x == z); // false
System.out.println(x.equals(y)); // true
System.out.println(x.equals(z)); // trueBecause x and y are literals, they reference the same pooled object, so == is true. z is a distinct heap object, making x == z false, while equals returns true for both comparisons.
@Test
public void testObject() {
Person p1 = new Person("Tom");
Person p2 = new Person("Tom");
System.out.println(p1.equals(p2)); // false
}
class Person {
private String name;
public Person(String name) { this.name = name; }
// No overridden equals method
}Since Person does not override equals, the default reference comparison is used, resulting in false even though the field values match.
Conclusion
Understanding the underlying JVM memory model and the specific implementation of String.equals() allows you to answer interview questions accurately, rather than relying on rote memorization. Remember: == checks reference identity; equals checks logical equality only when a class provides its own implementation.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Senior Brother's Insights
A public account focused on workplace, career growth, team management, and self-improvement. The author is the writer of books including 'SpringBoot Technology Insider' and 'Drools 8 Rule Engine: Core Technology and Practice'.
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.
