Value-based classes are types that are defined solely by their internal state and whose identity cannot be guaranteed at runtime. According to the documentation, a value-based class:

As such, instances of value-based classes should never be used with identity-sensitive operations, including reference equality (==) or identity hashing (System.identityHashCode()).

This rule raises an issue when an identity-sensitive operation is applied on a known value-based class. That includes:

Why is this an issue?

How to fix it

Use .equals() to compare instances of value-based classes for equality, and .hashCode() to compute their hashes.

Code examples

Noncompliant code example

Instant start = Instant.now();
Instant end = Instant.now();

if (start == end) { // Noncompliant: Comparing memory addresses, not temporal values.
  // ...
}


Optional<Integer> opt = Optional.of(1);
int hash = System.identityHashCode(opt); // Noncompliant

Compliant solution

Instant start = Instant.now();
Instant end = Instant.now();

if (start.equals(end)) { // Compliant: Comparing semantic values for equality.
  // ...
}

Optional<Integer> opt = Optional.of(1);
int hash = opt.hashCode(); // Compliant

Resources

Documentation