Solved

best practices pertaining to NullPointerException

Posted on 2006-06-15
21
467 Views
Last Modified: 2012-06-27
Any thoughts on best practices pertaining to NullPointerException handling...

Should all methods make it their business to be null-safe in order to be robust and invokable by any future client code that  may feed it null input OR is it better to not trash up the code and to just always make sure that there's a code layer (such as validation) that handles null input and to allow the rest of the code to not handle null input.

It has become a point of contention on our team, so I decided to turn this matter over to you, experts.
0
Comment
Question by:aturetsky
  • 8
  • 5
  • 3
  • +3
21 Comments
 
LVL 8

Expert Comment

by:Autogard
ID: 16913376
The idea of a code layer is a good idea, but I don't think it should be the only source of protection.  Especially if the functions are static functions in classes that may eventually get re-used by other programs that don't have such a layer to protect.  It's hard to "always make sure that there's a code layer" because you don't always know how the code will be used in the future.

Also I don't think adding NullPointerException handling really does "trash up the code" at all.  If safety is an important factor in your code (which I hope it is) then I think it's worth it.  Having both a layer and checking in the code, I think is a good idea.

That's my opinion.  :)
0
 
LVL 1

Author Comment

by:aturetsky
ID: 16913495
thanks for your vote, Autogard,

what does everyone else think?
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16913854
You should JUNIT test all critical code to see that null-pointer cases
are and REMAIN handled correctly.
Every constructor and setter should be prepared for bad data (from others).

;JOOP!
0
 
LVL 1

Author Comment

by:aturetsky
ID: 16914376
so can you then ever overdo it on null-checking?

is there ever a wrong time/place to do be doing null-checking
0
 
LVL 8

Expert Comment

by:Autogard
ID: 16914987
I would think only if your data can't possibly be null -- which it pretty much always can, or if having a null value can't hurt you at all.

I'm guessing you are on the side of the vote of too much null-checking being a bad thing?  ;)
0
 
LVL 1

Author Comment

by:aturetsky
ID: 16915003
hmm, sounds pretty unequivocal

any devil advocates here?
0
 
LVL 1

Author Comment

by:aturetsky
ID: 16915040
in other words, are there any cons, at all, whatsoever, to null-checking?
0
 
LVL 8

Assisted Solution

by:Autogard
Autogard earned 100 total points
ID: 16915125
A couple other views:

http://hoskinator.blogspot.com/ -- "Where should you check for NullPointerExceptions"
http://leepoint.net/notes-java/flow/assertions/assertions.html -- "Check for "impossible" conditions, not bad input"
0
 
LVL 1

Author Comment

by:aturetsky
ID: 16915307
>> http://hoskinator.blogspot.com/ -- "Where should you check for NullPointerExceptions"
that's a very helpful post

>> http://leepoint.net/notes-java/flow/assertions/assertions.html -- "Check for "impossible" conditions, not bad input"
very interesting article, I've got to try assertions.  Can you elaborate on what you take out of this one as it pertains to null pointer exceptions?

0
 
LVL 8

Expert Comment

by:Autogard
ID: 16915806
I thought that first article was more helpful as well.

From the second article, about all that I saw that was very interesting (from a devil's advocate point of view as you suggested) was "you must decide if the extra code is worth the better error diagnostic. In many cases the answer is "no"." -- but I'm not sure this relates exactly to what you are doing with null checking as the article is mostly about assertions, which they say to use in spots where execution should never occur.  Null-checking is used differently than assertions.
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 1

Author Comment

by:aturetsky
ID: 16915885
so, speaking of the case against null checking
I mean wouldn't it be correct to say that null checking should not be used to check for programmer errors in the client code  - I mean if the client code is buggy and fails to properly handle null input using invalid argument exceptions or what not, and instead passes nulls down the chain, then let it crash during development time and fix it.

No?
0
 
LVL 8

Expert Comment

by:Autogard
ID: 16915944
My main purpose for null-checking in the software would be to check user input more than anything.

As far as checking programming errors, yeah that to me is up to the testing of the software to handle.  As sciuriware mentioned, JUnit is a great way to do this.  Make sure your code can handle user stupidity and input and make sure your testers/testing can eliminate programmer stupidity and errors :)

That said, I still have an itch to say that you should make sure funky inputs don't crash your code even in a production environment -- users have funky ways of getting input there.  But I think what those other articles tried to explain is that it is ok to check for that at higher levels, which a layer or wrapper that is not necessarily connected to the lower code can't always guarantee.  Hmm, maybe I'm too paranoid though.  :)
0
 
LVL 19

Accepted Solution

by:
Jim Cakalic earned 150 total points
ID: 16917471
I try to apply a combination of heuristics in determining whether my code should perform null checking.

When I'm writing client code I try to determine whether it is my responsibility to check for null objects and how failing to do so may degrade/improve my code. If I'm writing code close to the user then I assume the worst -- data might be anything and it is probably my responsibility to report any problems. In that case I'm likely to check for things like null and empty Strings. I probably don't want to start tossing these values off to other objects because they're likely to throw NPEs when they try to use them. If there are multiple possibilities for null objects in a given code path, then it is probably easier for me to check, avoid the Exceptions, and report the "errors" directly.

If I'm writing what is arguably a "utility" method then I think about what I can reasonably expect of client code calling me and whether it should be their responsibility to provide valid inputs. You can take as an example classes in the JDK. The String class methods rarely check for null objects. Most methods simply reference objects passed in without ever checking to see if they are null. If an NPE results, oh well. One reason is that null checks aren't free. They may not cost much but when done millions of times the performance impact can be measured.

Joshua Block, the venerable designer of the Collections api and the author of the /Effective Java Language Programming Guide/ recommends that all parameters to a method be checked (http://www.informit.com/articles/article.asp?p=31551&rl=1). The major concern he expresses is that in some scenarios failure to check parameters, including nulls, lead to failures far from the point of origin of the error. That can make problem diagnosis quite difficult. The closer to the point where the error occurs the better. Of course, he doesn't always follow his own advice. If you look at the code to something like ArrayList, you'll find that object parameters are rarely checked. When they are, it is to choose between two equally valid code paths. When they are not, the javadoc for the method indicates that the method might throw a NPE.

So -- the still ambiguous advice is to check sometimes but not others. You need to evaluate the situation intelligently and determine what the impact of checking or not checking might be. In the cases where you choose not to check and your code might throw an NPE as a result, document that in the method javadoc so that clients of your objects know what to expect. Most importantly, try to be consistent as a team. You said it had become a matter of contention. Perhaps the team should meet and decide on their own set of heuristics to apply. Lay down the team rules for checking null object parameters and then everyone live with them. Even if they aren't what you might have preferred, the team will benefit from having a consistent style to rely upon. The code, at least in this case, will be more consistent and appear to have been written by a single individual. That is important to maintainability. And having a decision in your pocket, one way or another, will free all developers to go on to worrying about more important (business-oriented) design concerns.

Regards,
Jim Cakalic
0
 
LVL 30

Expert Comment

by:mayankeagle
ID: 16920423
The best place to start is method-arguments. If you don't expect any method-arguments to be null, then check them:

public void someMethod ( String a, String b, .... )
  throws MyException
{
  if ( a == null || b == null || .... )
    throw MyException ( "Parameter(s) cannot be null. " ) ;

  In your code, just make sure that you check for null before calling any method, like:

  String c = getSomeValue () ;
 
  if ( c != null )
  {
    // process 'c' by calling its methods, etc
  }

}

Some cases will already be handled by the compiler because it will not allow you to use uninitialized variables anyway. You just need to check for the ones whose values come from some other method(s)/ block(s).
0
 
LVL 4

Assisted Solution

by:fffej78
fffej78 earned 250 total points
ID: 16920682
Try the replace null with Null object pattern (a refactoring)

http://www.refactoring.com/catalog/introduceNullObject.html
http://www.industriallogic.com/xp/refactoring/nullObject.html

You can use documentation to ensure that the client does not make stupid assumptions.  Use annotations to mark parameters as non-null and generate the documentation accordingly.  See this spec.

http://cdsmith.twu.net/professional/java/pontifications/nonnull.html

You want your code to be clear.  If the code is being used by someone else, make sure the documentation is clear.  Try to avoid returning nulls if it all possible.

One of the commonest things I see people doing is returning null instead of something that would make more semantic sense.  For example, if you have something that returns a list some people prefer to return null instead of an empty list.  That's daft, return an empty list.  Similarly with a function that returns arrays, just return an empty array rather than null.

Basically minimise the internal uses of null in your codebase and document entry points such that it is clear whether parameters can be null.
0
 
LVL 1

Author Comment

by:aturetsky
ID: 16921730
jim_cakalic  - thanks for your thorough input - the rule is somewhat ambiguous but it makes sense

mayankeagle - so you're basically all for null checking, right?

fffej78 - great input - can you elaborate on the null object pattern - I read those two links but couldn't quite picture how exactly it would be used in the real world based on their examples; also, as far as the http://cdsmith.twu.net/professional/java/pontifications/nonnull.html goes - isn't that just a proposal, not something that already exists?

0
 
LVL 4

Assisted Solution

by:fffej78
fffej78 earned 250 total points
ID: 16922256
Null object pattern is explained in much more detail at http://www.cs.oberlin.edu/~jwalker/nullObjPattern/

Basically the aim is to make an "null" version of the object that has a sensible default action.  In the link above we create a "Null" object for a List class.  This allowed a "Null" list to react to messages and tidies code up.  For example, say I return a class X which has a method which accepts a single argument

class X
{
  void accept( Visitor v )
  {
    // Do some stuff
  }
}

Sometimes I haven't got a valid X to return, but I don't want to return null because that'd bloat my code with lots of null checking all over the place. My solution is to create a similar kinda of thing to null, but represented with an object instead.

// this would be a good candidate for the "Singleton" design pattern as there is only ever 1 representation of null for X
class NullX
  extends X
{
  void accept( Visitor v ) {  // do nothing }
}

This means I can write code such as

X x = getX(); // either returns an X if there is a valid X or NullX
x.accept( visitor ); //always succeeds even if x is "null" (because x isn't actually null, it's the null object!)

This isn't a great example, but the idea is to return an object with a default policy (implementation) for each of the methods of the object it is trying to be the null version of.  Hope that makes sense!  

There is a good article by Kevlin Henney on this available at:

http://www.two-sdg.demon.co.uk/curbralan/papers/europlop/NullObject.pdf  [warning PDF link!]

Hopefully that'll clear up any confusion on the null object pattern.

The annotations thing is just a proposal at the moment, but you could use J2SE 5 annotations to mark your code just for the purposes of documentation.  Have a look at https://nully.dev.java.net/ for an example of the sort of thing I'm imagining in the future.  You are right of course that it is something that doesn't exist (yet!)

0
 
LVL 30

Expert Comment

by:mayankeagle
ID: 16926604
>> so you're basically all for null checking, right

Right.
0
 
LVL 19

Assisted Solution

by:Jim Cakalic
Jim Cakalic earned 150 total points
ID: 16926806
Good input, fffej78.

Application of the null object pattern addresses the flip side of where the conversation was. Quite often it isn't important to distinguish between actual null and an object that does nothing. So frequently I'll return an empty String ("") instead of null when the return type is String. It might be important to enforce the "do-nothingness" of your null object. So instead of returning new ArrayList() when the response might otherwise be null, I often return Collections.EMPTY_LIST (or EMPTY_MAP or EMPTY_SET) because this both indicates an empty but not-null response to the client and it enforces the emptiness because EMPTY_LIST is immutable. It may not always be important but sometimes is. The important bit being, as pointed out by fffej78, that judicious use of the pattern can prevent some amount of null checking.

One consequence of a widespread application of the null object pattern is that you'll find yourself using interfaces much more frequently and passing objects that implement an interface instead of coupling to a concrete class. Not that this is bad. As a practioner of test-driven development I find that my code is much more loosely coupled by depending on the abstractions instead of concretions anyway. But it is a style that will take some time to get used to. Perhaps not everyone will like it or feel comfortable with it. When selling the idea of null-object to team members, you can mention this and be prepared to discuss the benefits of looser coupling and the dependency inversion principle (DIP). See http://www.objectmentor.com/resources/listArticles?key=topic&topic=Design%20Principles.

One point I failed to make before was evaluating the way in which null checking tends to obfuscate the code. When a method takes an object as an argument or accepts an object return from a method call and makes immediate use of it in a way that might case an NPE, adding null checking can tend to distract the focus from the problem that the method is trying to address. If you find it really is essential to check for null then having a utility class/method that can do the check and throw an appropriate run time exception collapses the null check into a one-liner. I find that stylistically much preferable than the two or three lines of code for each null check one might normally right -- if one is checking for nulls. ;-)

Jim
0
 
LVL 4

Assisted Solution

by:fffej78
fffej78 earned 250 total points
ID: 16926829
In response to Jim's excellent comments, it is definitely worth having a utility class for this sort of problem as there is there's nothing worse than seeing a 2 line method with 3 lines of null checking!

I've found the static import feature of Java5 useful.  I have a class a little like this:

public class Debug
{
  public static <T> T nonNull( T object )
  {
    assert object != null : "Non null object expected;
    return object;
  }
}

Then if I do a little static import I can write somewhat sensible looking code.

import static Debug.*;
public class Example
{
  public int method( A a, B b )
  {
    if ( nonNull( a ).equals( nonNull( b ) )
      return 7;
   else
     return -123;
  }
}

Which definitely is nicer than the alternatives of splatting extra null pointer checks everywhere!
0
 
LVL 1

Author Comment

by:aturetsky
ID: 16963294
Thanks to all your helpful input.  I will keep referring to your recommendations as we implement a new null handling policy.
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

For customizing the look of your lightweight component and making it look lucid like it was made of glass. Or: how to make your component more Apple-ish ;) This tip assumes your component to be of rectangular shape and completely opaque. (COD…
Introduction This article is the last of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers our test design approach and then goes through a simple test case example, how …
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now