DEV Community

Cover image for What I learned from Head First: Understanding == vs .equals() in Java
Mitchell Mutandah
Mitchell Mutandah

Posted on

What I learned from Head First: Understanding == vs .equals() in Java

Hello friends πŸ‘‹
Recently, I got confused about when to use == and .equals(). After careful analysis and referring to several sources, including YouTube videos, , I decided to put together this quick and friendly guide to clear things up! Don’t worry, I’ll keep it short and sweet.

Spoiler Alert: You might want to brush up on how stack memory works with objects before diving in! src - https://www.digitalocean.com/community/tutorials/java-heap-space-vs-stack-memory


Overview: The elephant in the room...

The distinction between == and .equals() is crucial, especially when dealing with object references and value comparisons. I will define the terms below for a better understanding.

== (Reference Comparison)

  • Used to compare primitive data types (like int, char, double).
  • When used with object references, it checks whether two references point to the same memory location (object).

Example:

String s1 = new String("Java");
String s2 = new String("Java");

System.out.println(s1 == s2); // false (different objects in memory)
Enter fullscreen mode Exit fullscreen mode

.equals() (Content Comparison)

  • Defined in the Object class and can be overridden in user-defined classes.
  • For objects, it is meant to compare the contents (state) of two objects rather than their memory locations.
  • By default, Object.equals() behaves like ==, but many classes (like String, Integer) override it to compare values. Example:
String s1 = new String("Java");
String s2 = new String("Java");

System.out.println(s1.equals(s2)); // true (same content)
Enter fullscreen mode Exit fullscreen mode

Example with Primitives and Wrapper Classes

int a = 10;
int b = 10;
System.out.println(a == b); // true (primitive values are the same)

Integer x = new Integer(10);
Integer y = new Integer(10);
System.out.println(x == y); // false (different objects)
System.out.println(x.equals(y)); // true (same content)
Enter fullscreen mode Exit fullscreen mode

Special Case: String Pool

String s1 = "Java";
String s2 = "Java";
System.out.println(s1 == s2); // true (same interned String object)
System.out.println(s1.equals(s2)); // true (same content)
Enter fullscreen mode Exit fullscreen mode

Explanation: "Java" is stored in the String pool, so s1 and s2 reference the same memory location.

My blindspot: primitives behaviour

I tried to come up with edge cases having all these fundamentals at hand. My mind was like, what if:

int a = 9;
short b = 9;

System.out.println(a == b); // ?
Enter fullscreen mode Exit fullscreen mode

Notice that we have short and int as different primitives. Let me break it down in 3 steps:

1. Understanding == with Primitives

  • The == operator compares values directly when dealing with primitive types.
  • Since both a and b are primitive numeric types (int and short), Java will perform an implicit widening conversion before comparing them.

2. Type Promotion in Java
When an arithmetic or comparison operation involves different primitive types, Java applies type promotion to ensure compatibility:

  • int is wider than short (since short is 16-bit and int is 32-bit).
  • Before performing the == comparison, Java automatically promotes b from short to int.
  • After promotion, both a and b become integers.

3.Final Comparison
After promotion:

int a = 9;  // remains int
int b = 9;  // promoted from short to int
Enter fullscreen mode Exit fullscreen mode

Now, the comparison:

System.out.println(a == b);
Enter fullscreen mode Exit fullscreen mode

will be true, since both are int and have the same value (9), the comparison returns true.


That's it! Hope it makes sense all the way. Got questions? Drop them in the comments, and let’s discuss!

Until next time.....

cheers

Top comments (0)