One fairly common coding style I have seen from more experienced developers is what I will call highly-aggressive null checking. Such developers have most likely been burned by null pointer exceptions in the past and hence have evolved a style of coding which confirms that parameters or fields are non-null before using them. The code below shows a typical example of this coding style.

public void placeOrder(Customer customer, Order order) { if (customer != null && order != null) { // ... } }

I am not a big fan of this style of coding, although I do appreciate that it results in more robust code than code that ignores null checking completely. My coding style instead uses precondition checks to assert that parameters or fields are not null before using them. Rewriting the above example in my style results in the following code.

public void placeOrder(Customer customer, Order order) { assert customer != null; assert order != null; // ... }

These two styles different in their approach to error handling: mine uses the fail fast principle, while the first uses the degrade gracefully principle. See my article on Fail Fast or Degrade Gracefully for details on the differences between the two. Long-time readers may find my preferred style surprising given my stated preference for the degrade gracefully approach. Let me clarify my position. I still do prefer the degrade gracefully approach, especially for the higher level application architecture & design. My use of fail fast at the detailed coding level is based primarily on my philosophical view of coding, which is to use the technical computer language (Java in the above example) to construct a language representing the business problem domain. The placeOrder method becomes part of the syntax of this business language that semantically only makes sense to apply to an actual customer & order. Having the method handle null arguments does not make sense when expressed in terms of the business language. From a more pragmatic viewpoint, having either the customer or order be null almost certainly reflects an error in the calling code. Blindly ignoring null values throughout the code base significantly increases the risk of errors going undetected.

One special case of aggressive null checking that really bothers me is checking for null collections. Below is an example:

public class Customer private List orders; public List getOrders() { return orders; } } public class CustomerProcessor { public void checkOrders(Customer customer) { if (customer.getOrders() != null) { for (Order order : customer.getOrders()) { // ... } } } }

In terms of the business domain, a customer can have zero or more orders. So the collection can be empty. But the relationship exists for every customer – a null collection has no business meaning. Checking if a collection is null therefore adds meaningless noise to a method. My approach instead is to have a class invariant that the collection is always defined, which then avoids the need for null checking. This is easily accomplished by initializing the collection at the time of definition. Rewriting the above code in my style results in the following:

public class Customer private List orders = new ArrayList (); public List getOrders() { return orders; } } public class CustomerProcessor { public void checkOrders(Customer customer) { for (Order order : customer.getOrders()) { // ... } } }

I believe that this style of coding is more readable and understandable, in large part because it more closely matches the problem domain being modeled without the baggage of extra null checks. This approach does require more thought regarding whether fields and parameters can or should be null, which is perhaps one reason why aggressive null checking is often used instead.

My approach can be compared to defining the nullity of columns in a database schema. One advantage with database design is column nullity is an explicit part of the database schema language, whereas programming languages such as Java provide no explicit support for the concept. I have long though that an explicit syntax for nullable versus non-nullable variables would be an interesting experiment. I have seen experimental languages with such a feature but I have not heard of any remotely mainstream language that does so. One possible syntax is to suffix nullable variables with a question mark. The compiler could then verify at compile time that such variables are checked if they are null before being used. Additionally at run time an exception could be thrown if a non-nullable variable is assigned a null value. Below is an example of what such a revision to Java would look like:

public void placeOrder(Customer customer, Order order, Discount? discount) { // Customer and Order are not nullable, Discount is nullable // Invoking a method on discount here would be flagged as an error by the compiler: double percentageDiscount = 1.00; if (discount != null) { // No error because we have checked if discount is null percentageDiscount = discount.calculatePercentage(); } // Can invoke methods on order and customer without checking if they are null. order.prepareToBePlaced(percentageDiscount); customer.addOrder(order); }

I am not a language designer so I do not know all the ramifications of such a language change. Therefore I am not saying that this should be added to Java, merely that it is a possibility. If you do want compiler support for dealing with nulls, then one alternative is to use the Eclipse IDE and enable its Java compiler for performing a static compile time analysis to warn of the use of variables that may be null (see image below).



Tweet

If you find this article helpful, please make a donation.