Mar 17, 2009

Null-safe method invocation in Java 7

There has been some discussion on null-safe method invocation in Java 7. Briefly there is a proposal to introduce a new ?. operator that would allow to call a method on a null object without throwing a NullPointerException (NPE). For instance:

   List list = null;
System.out.println(list?.isEmpty()); // prints: false

The most obtrusive part in the current state of proposals is assumption that the invocation on null object should always return null or a default value in case of primitives. In our example of list?.isEmpty() returning true would make much more sense then false, because semantically the null list does not have any elements so it is empty. The bottom line is that what the method returns when called on a null object is an implementation detail of that method, so it should be specified in the method's body. The rest of this post proposes a way to do it.

If the method's body starts with if (this == null) statement, e.g.

   class List {
public boolean isEmpty() {
if (this == null) return true;
return data.length == 0;
}
}

then Java 7 compiler could compile it to both the traditional method:

   public boolean isEmpty() {
// the if (this == null) ... block is removed
return data.length == 0;
}

as well as to a static wrapper method:

   private static boolean isEmptyNullSafe(List _this) {
if (_this == null) return true;
return _this.isEmpty();
}

(The name of the wrapper method must be generated by the compiler to prevent name clashes with methods already existing in the source code)

This way the isEmpty() method would work the same way if called normally:

   list.isEmpty()

, throwing NPE.

But the null safe call:

   list?.isEmpty()

would compile to:

   List.isEmptyNullSafe(list);

and return true, if the list is null.