Never return Null Arrays – really?

Scott Selikoff recently posted that we should “never return null arrays”. I’m not sure I entirely agree. Both the tone of the article and the comments so far seem to be in agreement, but I am still not so sure.

I’ll skip the terminology issue for the moment, just note that an array in Java is different, in syntax, interface and implementation, from a Collection. Scott’s article seems to discuss Collections rather than arrays.

As far as I am concerned, there is a qualitative distinction between a Collection which exists, but is empty, and a collection which simply does not exist (i.e is null). I’ll grant that in many situations they should result in the same action or output; but not always.

Imagine parsing XML documents. Consider the following three cases:

  <result>
  </result>
  <result>
     <stuff/>
  </result>
  <result>
     <stuff>
       <item id="1"/>
       <item id="2"/>
     </stuff>
  </result>

I suggest that first and second cases are different. It’s relatively easy to imagine that some software should behave differently in the case where the “stuff” block is not present at all, and in the case where it is present, but empty. A simplistic example might be that in the second and third cases a “Stuff” heading is rendered on a web page, but not in the first one.

If that abstract example is not enough to convince, consider the more practical example of an “all you can eat” buffet restaurant (pause for a Homer Simpson “mmm … buffet“). The way many of these places work is that when you arrive you pay a flat fee and receive an empty plate. You may then take that plate to the food and fill it with whatever you like. If you do not have a plate, you have not paid, and so can neither physically nor contractually fill it with food.

In this example the plate represents the collection. The state of having no (null) plate is very different from having an (empty) plate. The restaurant staff would be wise to know the difference.

Just for fun, here’s some java to illustrate:

public class Diner {
  private Wallet wallet;
  private Collection plate;
 
  public Diner() {
    wallet = new Wallet();
  }
 
  public void pay(Cashier cashier) {
    Money fee = wallet.extract(cashier.getFee());
    this.plate = cashier.payForPlate(fee);
  }
 
  public void selectFoodItem(Buffet buffet, Object item) {
    if (buffet.contains(item)) {
      buffet.grab(item, plate);
    }
  }
}
public class Buffet {
  public boolean contains(Object item) {
    return true; // the ultimate buffet :)
  }
 
  public void grab(Object item, Collection plate) {
    if (null == plate) 
      throw new RestaurantException("This is not a soup kitchen! Pay first or hit the road");
    if (plate.size() > 10)
      System.out.println("I see you brought your big plate, Alan");
    plate.add(item);
  }
}

The bottom line is that while the Null Object pattern is a very useful pattern, it should not be used indiscriminately. Just like any pattern, really.

Never return Null Arrays! | Down Home Country Coding With Scott Selikoff and Friends

I look forward to more thought-provoking posts from Scott and Jeanne!

3 Comments

  1. I completely agree that the Null Object pattern should only be used when it makes sense. I think the distinction Scott is making is that a list/array is a “special” type of object. In particular, a list of zero objects has meaning. If I do a query and get no objects back, an empty list semantically fits. Just like an empty ResultSet. Whereas if I query by primary key, it opens the debate of whether a null of null object is better.

    -Jeanne

  2. I consider Examples 1 and 2 the same. Functionally they serve the same purpose: to indicate the person has not provided any ‘stuff’. The syntax is different, but logically there shouldn’t be.

    The problem here is that you’re letting (plate == null) serve a dual, possibly ambiguous purpose. In this manner, your mixing the data about whether or not the person has paid and data about what the user is holding, which are contextually very different things. If the person has paid, there should be a boolean flag to indicate that such as “hasPaid = true”.

  3. In general, I agree. In many (most?) situations “no box” and “empty box” should be treated as the same thing, but surely you can also imagine situations where they should be dealt with differently?

    Perhaps it helps to start by considering some simpler objects before we get to collections. Is a null Integer always the same as 0? If so, what char is the same as a null Character?

    It is a fairly popular idiom that null means “not supplied” or “not available”, and informs the code that an application-specific default or some calculated value should be used instead. A null Integer might “mean” 0, 1, MAX_VALUE, the current time, etc. depending on the context or program state, so passing around a null to indicate this seems reasonable to me.

    The same idiom also seems reasonable for arrays and collections. A null means “not supplied” or “not available”, and client code is free to interpret that as appropriate. This interpretation may be as an empty array or collection, but also may be as some context-dependent default set of data.

    As for the plate example, it was mainly a bit of fun, but the point still stands. In the real world the absence of a container and the presence of an empty container are completely different, and many business processes rely on that difference.

    Your “hasPaid = true” example might be equivalent to giving each customer a receipt and requiring them to show that receipt every time they go over to the buffet. While there are no doubt some places which work this way, the restaurant business has largely accepted that this is a less efficient way to work. It requires a person (a.k.a. extra code) at the buffet to examine this receipt each time, slows down the buffet line (performance problems), can suffer from lost or unreadable receipts (bugs/exceptions) etc.

Comments are closed.