Q1 of 40 · Core Java
What is the difference between == and .equals() in Java?
Short answer
Short answer: == compares object references (memory addresses); .equals() compares object content. For String and all reference types, always use .equals() for value comparison — == only returns true if both variables point to the exact same object in heap memory.
Detail
In Java, every variable of a reference type holds a pointer to an object in heap memory. The == operator compares those pointers — two variables are == only if they reference the exact same object. Since most test code creates objects explicitly, == will almost never be what you want when checking content equality.
.equals() is the contract for value equality. The Object class provides a default that falls back to ==, but most standard types — String, Integer, List, LocalDate — override .equals() to compare content. That's the method you should call when you want to know whether two strings contain the same characters or two lists hold the same elements.
The gotcha that trips up new Java engineers is the string pool. String literals ("hello") are interned by the JVM, meaning "hello" == "hello" is typically true because both literals point to the same pooled object. But create either string with new String("hello") and you get a fresh heap object that == won't equal anything else. Tests that accidentally rely on string pool behaviour pass in one environment and fail in another — always use .equals().
For null safety, use Objects.equals(a, b) from java.util.Objects. It handles both sides being null without throwing a NullPointerException, which .equals() would throw if the left operand is null.
// EXAMPLE
EqualityDemo.java
String a = new String("hello");
String b = new String("hello");
System.out.println(a == b); // false — different heap objects
System.out.println(a.equals(b)); // true — same character sequence
// String pool: literals share a reference (don't rely on this in tests)
String c = "hello";
String d = "hello";
System.out.println(c == d); // true — same interned reference
System.out.println(c.equals(d)); // true — same content
// Null-safe comparison
String x = null;
System.out.println(Objects.equals(x, "hello")); // false, no NPE
System.out.println(Objects.equals(x, null)); // true