3

The NullPointerException in Java seems to only report that it occurred on a particular line of code. Is it possible to alter that exception to state which variable was null if there is more than one variable used in a line of code?

Freiheit
  • 8,408
  • 6
  • 59
  • 101
  • Sadly no, it'd be useful though – daniel gratzer Sep 25 '12 at 22:11
  • 4
    Isn't the line of code sufficient? – Kiril Sep 25 '12 at 22:11
  • @Lirik I presume the obvious answer is _yes_. When it comes to _spaghetti code_ the answer is _no_ I'm afraid... – pankar Sep 25 '12 at 22:14
  • why don't you point debugger at that line of code and determine which variable is null. Is your code not structured properly so, that you have couple of variables in single line? – questborn Sep 25 '12 at 22:14
  • @pankar if the code is such a spaghetti mess that one can't figure out which variable is `null` on a given line of code, then I would say there are **MUCH** bigger problems there. – Kiril Sep 25 '12 at 22:17
  • 2
    @pankar The problem really comes in chained method calls. If I have `something.getThis().getThat().getAnotherThing().whyAmIStillChaining().seriouslyWtf()` all on one line and get an NPE, the only easy way to figure it out is to pull it all apart and recompile/rerun. It's why I wish they had put the [Elvis operator](http://stackoverflow.com/questions/4390141/java-operator-for-checking-null-what-is-it-not-ternary) in Java 7. Oh well. I had this problem recently too -.- – Brian Sep 25 '12 at 22:31
  • Even if the call isn't chained like that, the actual (conceptual) error can be several calls away from where it was detected (perhaps by an API). (But I share a general distaste for "chained" calls, since they make debugging a bear and do not at all improve performance.) – Hot Licks Aug 26 '13 at 22:31

2 Answers2

4

No, the debug information in the class file does not contain enough information to allow this.

You can, however, improve on the situation. There are two things that can cause a NPE to be thrown:

  • A . dereferencing a variable, like foo.bar().
  • A [ indexing an array, like args[0].

If you write your code so there is only one of these on a given code line, there is simply no doubt about which one caused the NPE. It will introduce a lot of temporary variables but then you have more information readily available when debugging.

Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347
  • 5
    auto un-box is also a possible cause of null pointers. – Affe Sep 25 '12 at 22:27
  • I did not think of that. I have been on both sides of the fence regarding auto-boxing/unboxing, but I think I might come down on the side saying "as little magic as possible". In other words find out how to have the compiler flag autoboxing usages as errors and explicitly do the conversion manually. I believe the Eclipse compiler can do this, but have not checked. – Thorbjørn Ravn Andersen Sep 25 '12 at 22:45
  • Actually, THERE IS enough information to figure this out. You can find out which instruction triggers this NPE to be thrown. It'll boil down to an `invokevirtual` instruction, which takes only ONE operand. Then you can track back to which object it was invoked on - just take a little bit of work – One Two Three Oct 27 '16 at 02:52
  • @OneTwoThree interesting. do you have a link to a more detailed description of this? – Thorbjørn Ravn Andersen Oct 27 '16 at 07:15
1

No. NullPointerException does not always have to be caused by a variable/identifier being null. E.g. throw new NullPointerException() and throw null. Though it is often the case, it is not strictly required.

In most cases, it is fairly obvious what has caused the NPE. If not, then you may have too much going on in one line of code.

Consider this use case:

foo.doWork(bar1, bar2, bar3);

Here it is obvious that foo is `null.

Another case:

foo.doWork(bar.get(), bar2.get())

Here it could be foo, bar, or bar2.

The point is, that armed with this information and a breakpoint, it should be obvious what was null. If worse comes to worse, a static code analyzer like FindBugs could also give you some hints.

Tim Bender
  • 20,112
  • 2
  • 49
  • 58
  • What else is an NPE caused by? – Dave Newton Sep 25 '12 at 22:17
  • Ugh, iterating the cases would be rough. But it could be thrown as part of the guard pattern. Basically, a method that checks its arguments for `null` and then throws an NPE before doing work. For instance, some collections do this to avoid corrupting the data structure. Other application may be to just avoid the NPE happening organically. – Tim Bender Sep 25 '12 at 22:22
  • 1
    A random terrible coder could throw an NPE for fun. – Tim Bender Sep 25 '12 at 22:23
  • 1
    @DaveNewton You can also get an NPE from auto-boxing, such as doing `Integer val = null` and then passing it to `someMethod(int i)` like so: `someMethod(val);` – Brian Sep 25 '12 at 22:34
  • So, all caused by a variable, except when thrown explicitly. – Dave Newton Sep 25 '12 at 23:07