2012-02-01


I don't like NullPointerExceptions

Actually I don't like the message of NullPointer Exceptions, i. e. "null". Such a message is usually not very helpful.

I created a few rules for myself how to avoid certain exceptions and actually define pre- and post-conditions for methods. Let me please give you a few examples.

In the beginning of a non-private method I usually check all method arguments.

public void foo( String x, int a, Person p ) {
if ( x == null ) throw new IllegalArgumentException( "Argument 'x' must not be null." );
if ( a < 0 ) throw new IllegalArgumentException( "Argument 'a' must not be less than 0." );
if ( p == null ) throw new IllegalArgumentException( "Argument 'p' must not be null." );

A few hints:

There are of course libraries which do such checks, i. e. they can check if a String is not null and not empty, and if it contains only  white spaces and so on.
I would recommend to choose one of those libraries and use them intensively.
Otherwise some checks like in the example might be helpful.

There are also libraries which offer annotations for methods or method arguments to check if the method arguments are valid. Those libraries are great in my opinion, but often companies do not allow the use of some libraries for whatever reasons.

You can create your own Exception type or use an existing one. I have seen very often that developers use IllegalArgumentException, IllegalStateException, or NullPointerException. In the later case with a good error message...

These checks should not only be done in methods, but also in constructors, and whereever it makes sense for you.


For private methods I use assert statements. Remember assertion checking can be enabled and disabled by the command line options -ea and -da.

private void gee( Person p ) {
  assert p != null;
 
I usually do not add messages (too much work) to assertions. As we usually compile everything with the debug flag it is easy to find the line where the assertion error happened.

In the if statements from above or in such assert statements I always check only one thing.
That means that the following code is not OK for me:

assert p != null && p.getName() != null && !list.contains( p );

I prefer:

assert p != null;
assert p.getName();
assert !list.contains( p );


Before I return a value in a method, I check the value (post-condition) like in:

public String concat( String a, String b ) {
  ...
final String result = a + b;

assert result != null;
return result;


You can also add assert statements to various places within a method like:

public void addPerson( Person p ) {
  ...
  final int previousSize = list.size();
  list.add( p );
  assert list.size() == previousSize + 1;
  assert list.contains( p );

Remember that this code is not included in the class files, if you use the -da option, so there is no performance problem in production software, but those assertions can be great during development to find problems.
And they are a very good way to document assumptions. That is actually the most important point for me: I like executable documentation...


In addition I always check a reference before I call a method of if:

y = x.getName().toUpperCase();

will become:

if ( x != null and x.getName() != null ) {
  y = ...
 
Or one can also use assertions here, that depends on the context.

For me it is not so important which technology is used for all those checks, but that those checks are done at all.
I think it is a very important and actually very simple step toward increasing quality of software.


No comments:

Post a Comment