Proposal: Elvis and Other Null-Safe Operators

Jacek Kolodziejczyk jacek.p.kolodziejczyk at gmail.com
Thu Mar 19 01:26:45 PDT 2009


Hi,

In my opinion the most obtrusive part in the current state of proposals 
is assumption that the invocation on null object should always return null.
If I understand it correctly the following would break at runtime, 
because null cannot be assigned to boolean:

   List list = null;
   boolean b = list?.isEmpty();

Returning true by list?.isEmpty() would make much more sense, because 
semantically the null list does not have any elements, so it means it is 
empty. The bottom line is that <strong>what the method returns when 
called on a null object is an implementation detail of that 
method</strong>, so it should be specified in that method's body.

For another example if I wanted to print "Unknown" when person object is 
null, then every time I call Person.toString() I must write
    person?.toString() ?: "Unknown";
This violates the fundamental DRY principle. I could improve it by 
putting "Unknown" to a static field or a separate static method, but 
still the best would be if person?.toString() just returned "Unknown" 
when person is null.

The rest of this message proposes a way to introduce object oriented 
handling of null methods invocations (though I apologize this is not 
in-depth analysis)

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 this static method should be reserved by the compiler in 
such case 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.

Some discussion on this issue have taken place on my blog: 
http://codervirtue.blogspot.com/2009/03/null-safe-invocation-in-java-7.html#comments

Regards
Jacek Kolodziejczyk




More information about the coin-dev mailing list