== compares whether two references point to the exact same object in memory, while .equals() compares whether two objects are considered logically equal, based on how that class defines equality.
For primitive types (like int or char), == simply compares values directly, which is usually what you want. The confusion arises with objects, like Strings.
String a = new String("hello");
String b = new String("hello");
a == b // false — different objects in memory
a.equals(b) // true — same content
Even though a and b hold the same text, == returns false because they're two separate String objects. .equals() returns true because String overrides .equals() to compare actual character content rather than memory location.
Any custom class you write can override .equals() to define what "equal" means for that class. Using == on objects (other than when you specifically want to check if two variables reference the identical object) is a common source of subtle bugs for developers new to Java.
Last reviewed: September 2026