Back to Blog
Java

Java != Operator: Reference vs Value Comparison

java != operator: Learn how the != operator behaves for primitives and objects in Java, why it differs from equals(), and when to use each for correct comparisons.

Javaoperatorsequalityobject comparisonnull handling
Diagram showing Java != operator comparing primitive values vs object references.

The != operator in Java is a source of subtle bugs because its meaning depends entirely on whether the operands are primitives or objects. This article explains how java != operator behaves in both cases, where it diverges from equals(), and how to choose the right comparison for your code.

The != Operator for Primitive Types

For primitive types like int, double, boolean, char, the != operator compares the actual values. That means 5 != 3 evaluates to true, and 5 != 5 evaluates to false. The operator works directly on the numeric or boolean representation, so there is no ambiguity.

int a = 10; int b = 20; boolean notEqual = (a != b); // true

This is the straightforward use case. For float and double, != also works, but be careful with NaN. In Java, NaN != NaN is true because NaN is not equal to itself according to the IEEE 754 standard. This is often surprising but is the correct behavior for floating-point comparisons.

Reference Comparison for Objects

When you apply != to object references, it compares the references themselves, not the objects' contents. Two distinct objects with identical field values are still != because they occupy different memory locations.

String s1 = new String("hello"); String s2 = new String("hello"); boolean refsNotEqual = (s1 != s2); // true, because s1 and s2 are different objects

This is the root of many bugs. If you want to compare the logical content of objects, you must use the equals() method, which most classes override to define value equality. The != operator cannot be overridden; it always performs reference comparison for objects.

Why equals() Is Usually What You Want

For domain objects, strings, collections, and most other classes, the intent is almost always value equality. The equals() method is designed for that purpose. For example, String overrides equals() to compare character sequences.

String s1 = new String("hello"); String s2 = new String("hello"); boolean valuesEqual = s1.equals(s2); // true

When you write your own classes, you should override equals() (and hashCode()) to define what "equal" means for instances. Then use equals() in business logic, not !=. The only common exception is when you intentionally want to check whether two variables point to the exact same object, such as in identity-based caching or certain concurrency checks.

Common Mistakes with != and Objects

The most frequent mistake is using != to compare strings or custom objects for inequality. For example:

String input = getInput(); if (input != "expected") { // WRONG: compares references, not content // ... }

This often works by accident because of string interning, but it is unreliable. The correct version is:

if (!"expected".equals(input)) { // ... }

Notice the constant is placed on the left to avoid a NullPointerException when input is null. Similarly, for custom objects, always use !obj.equals(other) rather than obj != other.

Null Checks with != and ==

The != operator is the standard way to check for a non-null reference. Because null is a reference literal, obj != null is a reference comparison that returns true when obj points to any object, and false when it is null. This is safe and idiomatic.

if (obj != null) { obj.doSomething(); }

For the opposite check, obj == null is used. These checks are cheap and do not require equals(). However, do not use equals() to check for null, because calling obj.equals(null) will throw an exception if obj is null. The != null pattern is the recommended way to guard against null references.

Performance and Maintainability Considerations

Reference comparison with != is extremely fast because it only compares memory addresses. For null checks, it is the most efficient approach. In contrast, equals() may involve field-by-field comparison, which can be expensive for large objects. But you should not sacrifice correctness for speed. Use != only where reference identity is the actual requirement, and use equals() for value semantics.

Maintainability also matters. Code that uses != on objects often hides the developer's intent. A reader cannot tell whether reference identity was intentional or accidental. Using equals() makes the value comparison explicit. When you do need identity, consider naming variables or adding a comment to clarify why reference equality is required.

java != operator: Practical Usage and Code Examples | RYUSLOG DEV