RFR 9: 8138963 : java.lang.Objects new method to default to non-null
john.r.rose at oracle.com
Fri Oct 9 00:31:58 UTC 2015
On Oct 8, 2015, at 2:42 PM, Roger Riggs <Roger.Riggs at Oracle.com> wrote:
> Thanks for the insight, I hope it will help cut down on the thrashing.
> Isn't there a 4th form that throws missing?
There are four forms in Optional, but one of them returns "void" and is not relevant here, IMO. The third one I pointed out is the one that throws a programmable exception (e.g., IAE instead of NPE).
> There was quite a bit of support for a version the never returned null and threw an exception if the replacement was null.
This particular concern also transfers from Optional, with some forcing: Just as Optional::orElse cannot turn around and return an Optional::empty value, nonNullElse should not turn around and return a null. But, of course, the reason Optional::orElse doesn't return an empty is that the Java types forbid it (T != Optional<T>) while the issue is allowed by Java's always-nullable ref types.
Anyway, I agree with the consensus that nonNullElse and nonNullElseGet should throw NPE instead of returning nulls.
It may be instructive to link nulls to Optionals by encoding null-ness using Optional:
<T> T nonNullElse(T x, T y) := Optional.ofNullable(x).orElseGet(() -> Optional.ofNullable(y).get())
<T> T nonNullElseGet(T x, Supplier<T> y) := Optional.ofNullable(x).orElseGet(() -> Optional.ofNullable(y.get()).get())
<T> T nonNullElse(T x, T y) := Objects.requireNonNull( Optional.ofNullable(x).orElse(y) )
<T> T nonNullElseGet(T x, Supplier<T> y) := Objects.requireNonNull( Optional.ofNullable(x).orElseGet(y) )
This leads me to yet another bikeshed color, FWIW:
- T requireNonNull(T) (cf. Optional::get)
- T requireNonNullElse(T,T) (cf. Optional::orElse)
- T requireNonNullElseGet(T,Supplier<T>) (cf. Optional::orElseGet)
- T requireNonNullElseThrow(T,Supplier<X>) (cf. Optional::orElseThrow)
- T requireNonNull(T,String) (shorthand for common use of requireNonNullElseThrow)
This spelling makes it abundantly clear that the return value will *never* be null, unlike some other APIs.
I can imagine being content, as an IDE user, to see all of those options together, from a single completion gesture.
More information about the core-libs-dev