All 15 equals(), hashCode() & toString() Contracts questions
More in equals(), hashCode() & toString() Contracts
Advertisement
Java › equals(), hashCode() & toString() Contracts

What is the default behavior of equals() and hashCode() inherited from Object, and why is it usually necessary to override them for value-based classes?

Beginner

Answer

Object's default equals() implementation performs reference equality (== comparison, true only if both references point to the exact same instance), and its default hashCode() is typically derived from the object's memory address/identity -- for a value-based class (like a Point or Money class, where two separate instances with identical field values should be considered logically equal), these defaults are almost never what you want, since two distinct instances holding the same data would incorrectly be treated as unequal, requiring you to override both methods to compare actual field values instead of identity.
public class Point {
    int x, y;
    // No overrides
}

Point p1 = new Point(); p1.x = 1; p1.y = 2;
Point p2 = new Point(); p2.x = 1; p2.y = 2;
System.out.println(p1.equals(p2));  // false! Default equals() is reference equality, despite identical field values
Real-world example A bug report describing a Set<Point> that appears to allow duplicate coordinate pairs is traced to Point never overriding equals()/hashCode(), causing every new Point instance to be treated as unique regardless of its actual x/y values, since the default Object behavior compares object identity, not data.

Common follow-ups: What's the difference between == and .equals() for object references in Java?;Why does Object's default hashCode() typically use memory address rather than field values?