RFR 9: 8138963 : java.lang.Objects new method to default to non-null

John Rose john.r.rose at oracle.com
Wed Oct 28 23:44:34 UTC 2015


On Oct 9, 2015, at 8:46 AM, Roger Riggs <Roger.Riggs at oracle.com> wrote:
> 
> The primary purpose of the existing 'requireNonNull' methods is to check for null
> and throw an exception. It is used for explicit testing and producing a cogent exception.
> Returning the value was a secondary benefit that allowed it to be used in fluent expressions.

As I noted before, the stated purpose of "requireNonNull" can be slightly widened to check for null, and either throw an exception or return an alternative non-null value.  This is a compatible change.

Meanwhile, I just realized (after working on code in an IDE) that we already have this API point:

boolean nonNull(Object x) { return x != null; }

The new proposed name "nonNullElse" would seem on first glance to be a variation on that API point, but it's very different, since it returns T instead of boolean.  It seems to me that the prefix "nonNull" is already taken, and we have added an incompatible method to that family.	
The new API point "nonNullElse" is much closer in meaning to "requireNonNull", as noted before:

T nonNullElse(Object x, Object y) { return x != null ? x : y; }

T requireNonNull(Object x) { return x != null ? x : throw … }

Having different overloadings of the same name confuse T and a primitive type (boolean) is a known anti-pattern.  (Cf. List.remove(int|T).)  In this case, the names differ but "nonNull" and "nonNullElse" are going to be viewed together often as a group.  They are presented together in an IDE completer.  When I complete a name, I usually have in mind what I want it to return.  Therefore, the completion of "Objects.notN*" will show me a boolean-valued and a T-valued result, one of which is not what I want.  Meanwhile, if I were to complete "Objects.req*" I would get a choicer of T-valued operators, but not one particular one that I might want ("notNullElse").

As I said to you verbally, I'm not going to "die on this hill", but I do think the name chosen has some disadvantages that could have been avoided with a very slight mental shift about require.  I.e., "requireNonNull*" requires its *return value* to be not-null, so if its *argument* is null, then an adjustment is made (throw, select alternate value, get-from-supplier).

— John


More information about the core-libs-dev mailing list