Sunday, October 15, 2017

NullPointerException on non null object

Today I run into an odd problem. I was receiving NullPointerException (NPE) on a code, which simplified looked like this:

 if (input != null) {  
      process(input.getLength()); //This line was throwing NullPointerException  
 }  

I was puzzled. Because I am subscriber to Heinz Kabutz's newsletter about concurrency, I immediately suspect problem with threads. I had no idea how to test, if the problem is a result of thread run or something else, and I expected it to be a bit hard task. So I started to investigate the input variable and its content. I wrote short unit test to test given method.
  Soon I realized that if length (the return value of getLength() method) is null, the test crashes on NPE.
  That was really odd. But soon I realized where the problem was. The method process has signature

 private void process (int length) {  

and method getLength

 public Integer getLength() {  
   return length;  
 }  

The problem is that Java has to do unboxing, aka converting from Integer to int. It does it quietly in the background. It compiles the code from the first snipped to something like this:

 if (input != null) {  
      process(input.getLength().intValue());  
 }  

well because getLength() returns null, calling intValue() on null object produces NPE.

An odd problem, which took me some time to figure out. The resulting problem is a result of two other problems.
   First problem is broken implementation of method getLength(). The method should return int, because for an object (Integer) null is completely valid value. If for some reason it is necessary to return Integer, then for an empty object the method should return 0 instead of null. If null length represents uninitiated object, then this is broken design. There should be separate method for testing if the object is or isn't initiated.
  The second problem is autounboxing, which hides some code from the developer, which than fails. It should fail with message that unboxing failed due to null value. I wonder if it is possible to disable autounboxing in Eclipse (or Java compiler)?

No comments:

Post a Comment