Difference Between == and equals() in Java (String Trap)
== compares references (memory addresses), equals() compares content. Learn the String pool trap where == sometimes works and suddenly fails.
The one-line answer
== compares references (do both variables point to the same object in memory?); equals() compares content (do the objects hold the same data?).String a = new String("Java");
String b = new String("Java");
System.out.println(a == b); // false: two different objects
System.out.println(a.equals(b)); // true : same content
The String pool trap (why == "sometimes works")
String x = "Java"; // literal -> String pool
String y = "Java"; // same literal -> SAME pooled object
System.out.println(x == y); // true! (accidentally)
String z = new String("Java"); // new -> heap, outside pool
System.out.println(x == z); // false
== accidentally returns true for them. The moment a String comes from new, user input, a file, or concatenation at runtime — == fails. Rule: always compare Strings with equals(), never ==. This "works in testing, fails in production" bug is a famous interview story.equals() default behaviour in your own classes
class Student {
int roll;
Student(int r) { roll = r; }
}
Student s1 = new Student(101);
Student s2 = new Student(101);
System.out.println(s1.equals(s2)); // false!
Surprised? The default equals() from the Object class compares references — exactly like ==. To compare by content, you must override equals() (and hashCode()) in your class. That is why String, Integer etc. work with equals(): they have overridden it.
Comparison table
| Point | == | equals() |
|---|---|---|
| Type | Operator | Method (from Object class) |
| Compares | References / memory addresses | Content (if overridden) |
| Works on primitives | ✅ Yes (compares values) | ❌ No (primitives aren't objects) |
| Can be customised | Never | Yes — override in your class |
| Null safety | a == null is fine | a.equals(b) throws NPE if a is null |
Null-safe tip: write "admin".equals(role) (constant first) or use Objects.equals(a, b) — both avoid NullPointerException.
One-line answer
== references compare करता है (क्या दोनों variables memory में same object को point करते हैं?); equals() content compare करता है (क्या objects में same data है?).String a = new String("Java");
String b = new String("Java");
System.out.println(a == b); // false: दो अलग objects
System.out.println(a.equals(b)); // true : same content
String pool trap (== "कभी-कभी क्यों चलता है")
String x = "Java"; // literal -> String pool
String y = "Java"; // same literal -> SAME pooled object
System.out.println(x == y); // true! (गलती से)
String z = new String("Java"); // new -> heap, pool के बाहर
System.out.println(x == z); // false
== गलती से true दे देता है. जैसे ही String new, user input, file, या runtime concatenation से आए — == fail. Rule: Strings हमेशा equals() से compare करें, कभी == से नहीं. यह "testing में चला, production में fail" bug famous interview story है.अपनी classes में equals() का default behaviour
class Student {
int roll;
Student(int r) { roll = r; }
}
Student s1 = new Student(101);
Student s2 = new Student(101);
System.out.println(s1.equals(s2)); // false!
हैरान? Object class का default equals() references compare करता है — बिल्कुल == जैसा. Content से compare करने के लिए अपनी class में equals() override करना होगा (और hashCode() भी). इसीलिए String, Integer वगैरह equals() से चलते हैं: उन्होंने override किया हुआ है.
Comparison table
| Point | == | equals() |
|---|---|---|
| Type | Operator | Method (Object class से) |
| Compare करता है | References / memory addresses | Content (अगर overridden है) |
| Primitives पर | ✅ हां (values compare) | ❌ नहीं (primitives objects नहीं) |
| Customise हो सकता है | कभी नहीं | हां — अपनी class में override करें |
| Null safety | a == null ठीक है | a null हो तो a.equals(b) NPE देता है |
Null-safe tip: "admin".equals(role) लिखें (constant पहले) या Objects.equals(a, b) use करें — दोनों NullPointerException से बचाते हैं.
Frequently Asked Questions
What is the difference between == and equals() in Java?
== compares object references (memory addresses) while equals() compares content — provided the class has overridden equals(), like String and Integer do.
Why does "Java" == "Java" return true?
Both literals point to the same object in the String pool. The moment one String comes from new or runtime input, == returns false — so always use equals().
How to compare Strings safely against null?
Put the constant first — "admin".equals(role) — or use Objects.equals(a, b); both avoid NullPointerException.