Object Class: equals, hashCode, toString
हर class implicitly Object class extend करती है, इसलिए हर object को toString(), equals(), hashCode() free में मिलते हैं।
Default toString() अजीब सा text देता है (जैसे ClassName@hashcode) — इसलिए हम उसे override करते हैं readable output के लिए।
equals() और hashCode() को साथ में override करना चाहिए — HashMap/HashSet को सही से काम करने के लिए ये ज़रूरी है।
class Point {
int x, y;
public String toString() { return "(" + x + "," + y + ")"; }
public boolean equals(Object o) {
if (!(o instanceof Point)) return false;
Point p = (Point) o;
return x == p.x && y == p.y;
}
}- हर object को Object class से मिलते हैं
- toString() readable text के लिए override करो
- equals()+hashCode() साथ override करो
equals() का एक formal contract follow करना चाहिए: reflexive (a.equals(a) हमेशा true), symmetric (a.equals(b) == b.equals(a)), transitive (a=b और b=c तो a=c), और consistent (बिना data change किए बार-बार call करने पर same result)। इन rules को तोड़ने से Collections (HashMap, HashSet) में अजीब, hard-to-debug bugs आते हैं।
Rule: अगर दो objects equals() से equal हैं, उनका hashCode() भी same होना *चाहिए* (reverse ज़रूरी नहीं — अलग objects same hashCode share कर सकते हैं, "collision" कहलाता है, और HashMap इसे handle कर लेता है)। इसीलिए equals() override करते वक़्त hashCode() भी हमेशा साथ override करो, वरना HashMap/HashSet में duplicate detection fail हो जाएगा — same "equal" object दो बार add हो सकता है!
class Point {
int x, y;
public boolean equals(Object o) { /* x,y compare */ return true; }
public int hashCode() { return Objects.hash(x, y); } // dono saath
}Default toString() (ClassName@hashcode, जैसे Point@1b6d3586) debugging में useless होता है। Override करके meaningful representation दो — जैसे "Point{x=3, y=5}"। IDE और logging tools automatically toString() use करते हैं जब object print होता है या debugger में देखा जाता है।
हर object पर .getClass() call करके उसकी runtime class पता कर सकते हो (obj.getClass().getName()) — ये equals() implementation में instanceof के बजाय भी use होता है कभी-कभी (strict type matching के लिए)। ये "Reflection" API का entry point है — advanced feature जिससे runtime पर classes/methods inspect/call कर सकते हो (frameworks जैसे Spring इसी पर heavily depend करते हैं, dependency injection के लिए)।