Null pointer exceptions

Of the things which can go wrong at runtime in Java programs, null pointer exceptions are by far the most common. Recall that all values in Java programs are either scalars or references to objects, and that all variables have default values, which in the case of object references is null. Object references are like pointers in C, but are much more constrained: a C pointer can point to an arbitrary store location, while a Java object reference can point to an object of known type, or be null. When making a method call:

x.m()
there are therefore only two things that can go wrong: x might refer to a different object to that we intended, or it could be null. Fortunately, the latter is much more common in practice. The procedure for debugging null pointer exceptions is very simple:
  1. Identify the line where it occurred.
  2. Ask "what objects (or arrays) are being referenced on this line". One of them is null and it's usually obvious which.
  3. Figure out why it's null.
Usually the thing which is null is an instance variable, and it's null because of some cockup with the constructor. This can occur in many ways: I've seen all of the cases below occur in practice, most of them many times. Suppose we have a simple class:
public class Widget {
private int value;

public Widget(int v) { value = v; }

public int getValue() { return value; }
}
and another class which uses it:
public class Oops {

private Widget theWidget;

public static void main(String[] args) {
Oops myInstance = new Oops();
System.out.println(myInstance.theWidget.getValue()); 
}
}
Obviously, when we run this we get a nullPointerException (1), because theWidget has its default value of null, courtesy of the default constructor for class Oops. (In principle, there are four things on the line which could be null - four dots - but we can hopefully rule out System and System.out, and we just created myInstance, so it has to be theWidget).

So we need to provide an appropriate constructor, which will either take a Widget as a parameter, or create one. In the former case, we ought to use a meaningful name for the parameter, and it's tedious to keep inventing meaningful names, so let's use the same name as the instance variable:

public Oops(Widget theWidget) {
theWidget = theWidget;
}

nullPointerException (2). Oh, of course, we forgot to change the main program, the default constructor's still getting called.

...
Oops myInstance = new Oops(new Widget(42));
...
NullPointerException (3) Eh? The problem is that both sides of the assignement
theWidget = theWidget;
refer to the parameter, not to the instance variable, which isn't touched. One solution - actually the one I use, is to explicitly say 'this.' on the left hand side. I used to think this was completely safe, but:
public Oops(Widget theWiget) {
this.theWidget = theWidget;
}

nullPointerException (4) Que? This time, because of the mis-spelling of the parameter name, both sides of the assignment refer to the instance variable, and it still doesn't get set properly.

Possibly the safest way is to use the same names, but decorate one or the other by some systematic convention like a leading underscore. (I think it's better to decorate the parameter, because that will probably only be referred to once, but some people prefer to decorate instance variables.)

public Oops(Widget _theWidget) {
this.theWidget = _theWidget;
}

The this. is now redundant, but I find it clearer to leave it in. The only thing which can go wrong now is if the parameter is null:

...
Oops myInstance = new Oops(null);
...
nullPointerException (5). In general, the caller of a constructor (or a method in general) is responsible for providing sensible parameters, and you shouldn't assume null is ok unless the documentation explicitly says so.

Now suppose we create the widget in the constructor:

public Oops() {
Widget theWidget = new Widget(42);
}
...
Oops myInstance = new Oops();
...
nullPointerException (6). This time, the left hand side of the assignement is a local variable in the constructor, and again the instance variable isn't touched.

Finally, my favourite:

public void Oops() {
this.theWidget = new Widget(42);
}
...
Oops myInstance = new Oops();
...
nullPointerException (7). I'll give you the option of figuring this one out for yourself. The answer is here.

These all look like pretty dumb mistakes when presented this way, but remember that normally there's a lot of other code around to confuse the issue.