Objects.nonNull()

Stephen Colebourne scolebourne at joda.org
Fri Jan 14 11:30:59 UTC 2011


There are a number of strands to this thread

1) Null useful or not.
There are arguments on both sides here, and developers are divided.
Personally, I use null every single day to use not known or not
required, such as in a search request:

  /**
   * The set of exchange object identifiers, null to not limit by
exchange object identifiers.
   * Note that an empty set will return no exchanges.
   */
  private List<UniqueIdentifier> _exchangeIds;
  /**
   * The exchange keys to match, null to not match on exchange keys.
   */
  private IdentifierSearch _exchangeKeys;
  /**
   * The exchange name, wildcards allowed, null to not match on name.
   */
  private String _name;

For me, null is incredibly useful. I understand those that want it
removed, or push against it - I just disagree. (Thats why I want
better null-handling syntax features). BTW, I believe but can't prove
that far more people in the real world make use of null than avoid it.

2) Other utilities
These are prior art that users are familiar with, just as much as the JDK.
Google Guava - Objects:
  public static <T> T firstNonNull(T first, T second)

Google Guava - Preconditions:
  public static <T> T checkNotNull(T reference)

Commons Lang - ObjectUtils:
  public static Object defaultIfNull(Object object, Object defaultValue)

Commons Lang - StringUtils:
  public static boolean isEmpty(String str)
  public static boolean isNotEmpty(String str)
  public static boolean isBlank(String str)
  public static boolean isNotBlank(String str)
  public static String trimToNull(String str)
  public static String trimToEmpty(String str)
  public static String defaultString(String str)
  public static String defaultString(String str, String defaultStr)
  public static String defaultIfEmpty(String str, String defaultStr)

3) Prior discussions
When this was first raised I argued for the addition of a Validate
(Commons Lang)/Preconditions (Google Guava)/Assert (JUnit) class
alongside and separate from Objects. The "notNull" method would make
much more sense there with its given name.

  Validate.notNull(foo)

4) Fluency
The Objects.notNull code is designed for writing fluent code that
asserts the non-null status of the value.

public void process(String foo) {
  if (nonNull(foo).length() > 3) { ... }
}

This is a style/taste thing. Personally I prefer:

public void process(String foo) {
  Validate.notNull(foo);
  if (foo.length() > 3) { ... }
}

I believe that the latter (my choice) is more in the spirit of the
Java core libraries. (And I've used the latter style for many years
with great success, whereas I wouldn't touch the assert keyword with a
bargepole)

It is critical to understand that the basis of the method as written
is the fluency. Therefore "checkNotNull" simply isn't as readable:

  if (checkNotNull(foo).length() > 3)

The suggestion of "nullChecked" is more fluent:

  if (nullCheked(foo).length() > 3)

However, I still argue that this kind of fluency is not appropriate
for such a core JDK class when compared to the Validate/Preconditions
alternative.

5) Now
*** If you are time-pressured, I'd recommend removing this method from v7. ***

A "defaultIfNull" method would be much more useful in this class:
    public static Object defaultIfNull(Object object, Object defaultValue) {
        return object != null ? object : defaultValue;
    }
andf much more in keeping (I wouldn't ever want to see the above
method just called "notNull".

Stephen


On 14 January 2011 05:23, Brian Goetz <brian.goetz at oracle.com> wrote:
> Thinking some more:
>
>  - The name nonNull() is just confusing.  It could reasonably mean one of
> several things, and we've seen this in people's reactions: some don't like
> it for the throwing behavior because its not clear that it has a strong
> checking behavior, others don't like it for the defaulting behavior because
> the find the defaulting behavior unnatural.  This suggests it is just too
> vague to make anyone happy.
>  - I'm still enamored of checkNonNull() for the throwing version but am
> still open to better names.
>  - If we add carpet-sweeping versions later, asNonNull() or makeNonNull()
> both seem better than nonNull().
>  - We just stay away from the not-specific-enough name nonNull() here.
>
>
>
> On 1/13/2011 7:20 PM, mark.reinhold at oracle.com wrote:
>>>
>>> Date: Thu, 13 Jan 2011 18:15:30 -0500
>>> From: brian.goetz at oracle.com
>>
>>> ...
>>>
>>> Between checkNonNull() and throwIfNull(), I lean towards the former.  In
>>> any
>>> case the answer should be driven by what is more obvious to the reader.
>>
>> Agreed.
>>
>>>
>>>  So
>>> let's look at some typical code:
>>>
>>>   public Moo fooWrapper(String x, String y) {
>>>       return foo(throwIfNull(x), throwIfNull(y));
>>>   }
>>>
>>> vs
>>>
>>>   public Moo fooWrapper(String x, String y) {
>>>       return foo(checkNonNull(x), checkNonNull(y));
>>>   }
>>>
>>> Since throwing should be the exceptional path, it feels to me that having
>>> throw
>>> in the name sets slightly the wrong expectations.  ...
>>
>> Agreed.
>>
>> I'm still troubled by the "check" prefix, though.  It implies that the
>> named condition will be tested but it doesn't clearly relate the result
>> of that test to the method's exception-throwing behavior.
>>
>> Here's an idea: Why not treat this as a (degenerate) kind of conversion
>> operation?  Call it asNonNull(x) -- it (trivially) converts its argument
>> to a non-null value, and if it can't then it throws an NPE.
>>
>>   public Moo fooWrapper(String x, String y) {
>>       return foo(asNonNull(x), asNonNull(y));
>>   }
>>
>> Of all the names we've considered, this looks the most natural to me.
>>
>> - Mark
>



More information about the core-libs-dev mailing list