RFR 9: 8138963 : java.lang.Objects new method to default to non-null (original) (raw)
Roger Riggs roger.riggs at oracle.com
Fri Oct 30 19:07:33 UTC 2015
- Previous message: RFR 9: 8138963 : java.lang.Objects new method to default to non-null
- Next message: RFR 9: 8138963 : java.lang.Objects new method to default to non-null
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Hi John,
Thanks for the followup.
It is a subtle issue and seems to hinge on the relative priority of consistency in naming and the degree that historical artifacts ('mistakes') constrain contemporary patterns.
If we were re-writing history: boolean nonNull(obj) could/should have been named 'isNonNull'. T nonNull(T, String) could/should have been T nonNullThrows(T, Supplier)
The notion that the prefix "nonNull" is already taken and the anti-pattern, seem a lower priority. The prefix can be understood to introduce a family of similar not necessarily identical semantics. Most method names try to describe the action taken, not the pre- or post-conditions.
I prefer shorter names and was ready to capitulate until I ran into this:
T requireNonNull(T)
T requireNonNull(T, String)
T requireNonNull(T, T) -- now is ambiguous with the
pre-existing method
So just add another word to disambiguate: T requireNonNullElse(T, T) -- now 23 characters counting required punctuation without room for the return value or arguments. T requireNonNullElseGet(T, Supplier)
The shorter names were intended to be easier to read and save the space on the line for the arguments which are the important parts of the expression.
The longer names disambiguate adequately but add to the bulk of the code. I see maturing systems end up being weighed down by the seemingly necessary qualification.
So in face of the tradeoffs, what were you proposing again?
Roger
On 10/28/15 5:44 PM, John Rose wrote:
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
- Previous message: RFR 9: 8138963 : java.lang.Objects new method to default to non-null
- Next message: RFR 9: 8138963 : java.lang.Objects new method to default to non-null
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]