Object Equality vs Identity
Object equality vs identity explained — == vs .equals(), default Object behavior, and why hashCode() must match equals() in Java.
Expected Interview Answer
Identity means two references point to the exact same object in memory (checked with == in Java), while equality means two references point to objects considered logically equivalent by some definition of sameness (checked with .equals()), and two objects can be equal without being identical.
The == operator on reference types compares memory addresses — it answers "are these the same object instance?" The .equals() method, when properly overridden, answers a different question: "do these two objects represent the same logical value?" For example, two separate String objects containing "hello" are not identical (different memory locations from new String(...)) but are equal (same character sequence). By default, Object.equals() falls back to identity comparison (==), so any class that wants value-based equality must override equals() explicitly. This distinction matters for collections: HashSet and HashMap rely on equals() (paired with hashCode()) to detect duplicates or look up keys, not on identity.
- Prevents subtle bugs from using == on objects that need value comparison
- Explains why collections like HashSet rely on equals()/hashCode()
- Clarifies default Object behavior vs custom-overridden behavior
- Foundational for understanding immutable value objects
AI Mentor Explanation
Two different bats from the same manufacturer, same model, same willow grade are equal in every measurable way, but they are not identical — they are physically separate pieces of wood in separate hands. Identity asks "is this the exact same physical bat I held yesterday?" while equality asks "is this bat the same specification as that one?" A scorer comparing two players’ bats for a spec check cares about equality; an umpire checking if a specific bat was tampered with cares about identity.
Step-by-Step Explanation
Step 1
Distinguish the two questions
== asks "are these the same object instance?"; .equals() asks "are these logically the same value?"
Step 2
Check the default behavior
Object.equals() defaults to == (identity) unless the class overrides it.
Step 3
Override equals() for value types
Classes representing values (Point, Money, custom keys) should override equals() to compare meaningful fields.
Step 4
Verify collection reliance
HashSet/HashMap use equals() and hashCode() together to detect logical duplicates, not identity.
What Interviewer Expects
- A precise definition distinguishing == (identity) from .equals() (logical equality)
- Knowledge that Object.equals() defaults to identity comparison
- Awareness that overriding equals() without hashCode() breaks hash-based collections
- A concrete example, e.g. two equal-but-not-identical String or custom objects
Common Mistakes
- Using == to compare String or wrapper-object content instead of .equals()
- Overriding equals() without also overriding hashCode()
- Assuming equal objects are always identical, or vice versa
- Forgetting that the equals() contract requires reflexivity, symmetry, and transitivity
Best Answer (HR Friendly)
“Identity means two references literally point to the same object in memory, while equality means two objects are considered the same value even if they are separate instances. In Java, == checks identity and .equals() checks equality, and by default equals() just falls back to identity unless a class overrides it to compare actual field values.”
Code Example
String a = new String("hello");
String b = new String("hello");
System.out.println(a == b); // false -- different objects (identity)
System.out.println(a.equals(b)); // true -- same character content (equality)
class Point {
int x, y;
Point(int x, int y) { this.x = x; this.y = y; }
@Override
public boolean equals(Object o) {
if (!(o instanceof Point p)) return false;
return x == p.x && y == p.y;
}
@Override
public int hashCode() { return Objects.hash(x, y); }
}
Point p1 = new Point(1, 2);
Point p2 = new Point(1, 2);
System.out.println(p1 == p2); // false -- different instances
System.out.println(p1.equals(p2)); // true -- same logical valueFollow-up Questions
- What is the equals()/hashCode() contract in Java?
- What happens if you override equals() but not hashCode()?
- Why does == work correctly for interned String literals but not for new String(...)?
- How do record types in Java handle equals() and identity differently from regular classes?
MCQ Practice
1. What does == compare for reference types in Java?
== on reference types checks whether both variables point to the exact same object in memory.
2. What does Object.equals() do by default, before any override?
The default Object.equals() implementation simply compares references, i.e. identity.
3. Why must hashCode() be overridden whenever equals() is overridden?
Hash-based collections rely on equal objects having equal hash codes; violating this breaks lookups.
Flash Cards
Identity in one line? — Two references point to the exact same object instance (== in Java).
Equality in one line? — Two objects are considered the same logical value (.equals() in Java).
Default equals() behavior? — Falls back to identity comparison unless explicitly overridden.
Golden rule when overriding equals()? — Always override hashCode() too, consistently with equals().