6

The java.util.Optional javadoc states that:

This is a value-based class; use of identity-sensitive operations (including reference equality (==), identity hash code, or synchronization) on instances of Optional may have unpredictable results and should be avoided.

However, this junit snippet is green. Why? It seems to contradict the javadoc.

    Optional<String> holder = Optional.ofNullable(null);
    assertEquals("==", true, holder == Optional.<String>empty());
    assertEquals("equals", true, holder.equals(Optional.<String>empty()));
zr0gravity7
  • 2,917
  • 1
  • 12
  • 33
Jacques René Mesrine
  • 46,127
  • 27
  • 66
  • 104
  • 6
    Passing *one* simple test doesn’t allow to derive a general rule. If the *specification* says that you can’t rely on this behavior, then you shouldn’t rely on this behavior. – Holger Feb 12 '15 at 21:12

2 Answers2

6

You shouldn’t draw any conclusions from the observed behavior of one simple test ran under a particular implementation. The specification says that you can’t rely on this behavior, because the API designers reserve themselves the option to change the behavior at any time without notice.

The term Value-based Class already provides a hint about the intended options. Future versions or alternative implementations may return the same instance when repeated calls with the same value are made, or the JVM might implement true value types for which identity based operations have no meaning.

This is similar to instances returned by the boxing valueOf methods of the wrapper types. Besides the guaranty made for certain (small) values, it is unspecified whether new instances are created or the same instance is returned for the same value.

“A program may produce unpredictable results if it attempts to distinguish two references to equal values of a value-based class…” could also imply that the result of a reference comparison may change during the lifetime of two value-based class instances. Think of a de-duplication feature. Since the JVM already has such a feature for the internal char[] array of Strings, the idea of expanding this feature to all instances of “value-based classes” isn’t so far-fetched.

Holger
  • 285,553
  • 42
  • 434
  • 765
0

Optional.of() makes a new Object for every non-null value. So it is very likely that comparing 2 Optionals will be two references even if the Optional refers to the same value.

However, your example shows that Optional.empty() re-uses the same singleton instance. That is probably the only time the same Optional instance is ever returned twice.

dkatzel
  • 31,188
  • 3
  • 63
  • 67