Java developers often mix up the operator == vs .equals() in Java, leading to unexpected bugs. While both are used for comparison, they serve distinct purposes. Understanding the difference between == and .equals() in Java is critical for accurate Java object comparison and avoiding logical errors. Let’s demystify these concepts with clear examples and use cases.
Table of Contents
== Operator vs .equals() Method: Core Differences
1. == Operator: Compares References or Primitive Values
The Java equality operator (==
) checks if two variables point to the same memory location (for objects) or hold the same value (for primitives).
Example with Primitives:
int a = 5;
int b = 5;
System.out.println(a == b); // true (values are equal)
Example with Objects:
String s1 = new String("Hello");
String s2 = new String("Hello");
System.out.println(s1 == s2); // false (different memory addresses)
2. .equals() Method: Compares Object Content
The equals method Java classes (like String
, Integer
) override this method to compare the actual content of objects, not their memory addresses.
Example:
String s1 = new String("Hello");
String s2 = new String("Hello");
System.out.println(s1.equals(s2)); // true (content is identical)
When to Use == vs .equals() in Java
Use ==
For:
- Primitive type comparisons (e.g.,
int
,char
). - Checking if two object references point to the same instance.
Use .equals()
For:
- Java object comparison (e.g.,
String
, custom classes). - Comparing logical equality (e.g., two different
Integer
objects with the same value).
Common Use Cases
1. Java String Comparison
Strings are a classic example where using ==
can fail:
String literal1 = "Java";
String literal2 = "Java";
String obj1 = new String("Java");
String obj2 = new String("Java");
System.out.println(literal1 == literal2); // true (shared pool memory)
System.out.println(obj1 == obj2); // false (different objects)
System.out.println(obj1.equals(obj2)); // true (content matches)
2. Custom Objects
By default, .equals()
behaves like ==
unless overridden. Always override .equals()
(and hashCode()
) for meaningful Java object comparison:
class Person {
String name;
Person(String name) { this.name = name; }
@Override
public boolean equals(Object obj) {
if (obj instanceof Person) {
return this.name.equals(((Person) obj).name);
}
return false;
}
}
Person p1 = new Person("Alice");
Person p2 = new Person("Alice");
System.out.println(p1 == p2); // false
System.out.println(p1.equals(p2)); // true (after overriding)
Pitfalls to Avoid
1. NullPointerException with .equals()
Calling .equals()
on a null
object crashes the code:
String s1 = null;
System.out.println(s1.equals("test")); // Throws NullPointerException
To fix this issue, either we need to use Objects.equals(s1, "test")
or check for null first.
Example:
String s1 = null;
System.out.println(Objects.equals(s1, "test"));
This prints the output as false
.
2. Mixing == and .equals() for Wrapper Classes
Integer a = 127;
Integer b = 127;
System.out.println(a == b); // true (cached values)
Integer c = 200;
Integer d = 200;
System.out.println(c == d); // false (outside cache range)
Key Takeaways
==
: Compares primitive values or object references..equals()
: Compares object content (override for custom logic).- Strings: Always use
.equals()
for Java string comparison. - Null Safety: Prefer
Objects.equals()
to avoidNullPointerException
.
Conclusion
Mastering the difference between == and .equals() in Java is essential for writing bug-free code. Use ==
for primitives and memory-based checks, and rely on .equals()
for logical Java object comparison. Always override .equals()
in custom classes and stay cautious with == vs .equals() in Java scenarios involving strings or wrapper objects.
By applying these principles, you’ll avoid common pitfalls and ensure accurate comparisons in your Java projects.