How to trace a NullPointerException in a chain of getters

Lena Schimmel picture Lena Schimmel · Jan 4, 2009 · Viewed 8.3k times · Source

If I get a NullPointerException in a call like this:

someObject.getSomething().getSomethingElse().
    getAnotherThing().getYetAnotherObject().getValue();

I get a rather useless exception text like:

Exception in thread "main" java.lang.NullPointerException
at package.SomeClass.someMethod(SomeClass.java:12)

I find it rather hard to find out which call actually returned null, often finding myself refactoring the code to something like this:

Foo ret1 = someObject.getSomething();
Bar ret2 = ret1.getSomethingElse();
Baz ret3 = ret2.getAnotherThing();
Bam ret4 = ret3.getYetAnotherOject();
int ret5 = ret4.getValue();

and then waiting for a more descriptive NullPointerException that tells me which line to look for.

Some of you might argue that concatenating getters is bad style and should be avoided anyway, but my Question is: Can I find the bug without changing the code?

Hint: I'm using eclipse and I know what a debugger is, but I can't figuer out how to apply it to the problem.

My conclusion on the answers:
Some answers told me that I should not chain getters one after another, some answers showed my how to debug my code if I disobeyed that advice.

I've accepted an answer that taught me exactly when to chain getters:

  • If they cannot return null, chain them as long as you like. No need for checking != null, no need to worry about NullPointerExceptions (be warned that chaining still violates the Law of Demeter, but I can live with that)
  • If they may return null, don't ever, never ever chain them, and perform a check for null values on each one that may return null

This makes any good advice on actual debugging useless.

Answer

Esko picture Esko · Jan 5, 2009

NPE is the most useless Exception in Java, period. It seems to be always lazily implemented and never tells exactly what caused it, even as simple as "class x.y.Z is null" would help a lot in debugging such cases.

Anyway, the only good way I've found to find the NPE thrower in these cases is the following kind of refactoring:

someObject.getSomething()
          .getSomethingElse()
          .getAnotherThing()
          .getYetAnotherObject()
          .getValue();

There you have it, now NPE points to correct line and thus correct method which threw the actual NPE. Not as elegant solution as I'd want it to be, but it works.