Take the 2-minute tour ×

I've always wondered why the JVM doesn't tell you which pointer (or more precisely, which variable) is null when a NullPointerException is thrown.

A line number isn't specific enough because the offending line can often contain numerous variables that could have caused the error.

Is there any compiler or JVM flag that would make these exception messages more useful?

share|improve this question
This really hasn't ever been a problem for me in 8+ years of being a professional Java developer. If you've got a lot of references that might be null on one line, it may be time to break it out into multiple lines. –  MattC Jul 22 '09 at 22:06
@mattc, you never work with other peoples library code? –  Thorbjørn Ravn Andersen Jul 22 '09 at 22:51
@MattC: This often comes up when you need to call a function with several arguments in a condition the middle of a long if-else-if block. Breaking it out into multiple lines would mean going up and declaring a bunch of dummy variables before the top of the if. I would say that in most cases this would be more problematic in terms of code readability and style. –  kpozin Jul 23 '09 at 14:28
I asked a similar how-to-debug question on the same problem but finally got convinced to write my code in a way that does not throw NPEs. See stackoverflow.com/questions/410890/… –  Lena Schimmel Aug 17 '09 at 21:55
add comment

7 Answers

up vote 35 down vote accepted

It's because the dereference always happens when there is no name available. The value is loaded onto the operand stack, and is then passed to one of the JRE opcodes that dereferences it. However, the operand stack does not have a name to associate with a null value. All it has is 'null'. With some clever runtime tracking code, a name can be derived, but that would add overhead with limited value.

Because of this, there is no JRE option that will turn on extra information for null pointer exceptions.

In this example, the reference is stored in local slot 1, which maps to a local variable name. But the dereference happens in the invokevirtual instruction, which only sees a 'null' value on the stack, and then throws an exception:

15 aload_1
16 invokevirtual #5

Equally valid would be an array load followed by a dereference, but in this case there is no name to map to the 'null' value, just an index off of another value.

76 aload    5
78 iconst_0
79 aaload
80 invokevirtual #5

You can't allocate the names statically to each instruction either - this example produces a lot of bytecode, but you can see that the dereference instruction will receive either objA or objB, and you would need to track this dynamically to report the right one, as both variables flow to the same dereference instruction:

(myflag ? objA : objB).toString()
share|improve this answer
+1 For an actual explanation as opposed to "if you write code 'the right way' this doesn't happen to you". –  Zarkonnen Jul 22 '09 at 22:16
JVM should be able to tell us which instruction caused NPE, though, and I think that's still tremendously useful, for example if an expression "a.b.c.d.e.f" results in NPE. –  Kohsuke Kawaguchi Jan 25 '10 at 21:37
add comment

Once you JIT the code, it's just native pointer math, and if any pointer in the native code is null it throws the exception. It would have a devastating performance impact to reverse that assembly back to the original variable, and considering the JIT optimizes the generated code to varying levels, is often not even possible.

share|improve this answer
Capped my rep again right before this post. LOL :o –  280Z28 Jul 22 '09 at 21:14
@Michael: The JIT tracks line numbers during native code generation. It doesn't track at a higher resolution than that (sub-expressions, etc.). –  280Z28 Jul 22 '09 at 21:15
@Michael: Sorry, I was speaking from the CLI JIT: See the description for the "Default" member here: msdn.microsoft.com/en-us/library/… –  280Z28 Jul 22 '09 at 21:36
@Michael, early Sun JITs lost linenumber info. Hotspot can show it even for jitted code. –  Thorbjørn Ravn Andersen Jul 22 '09 at 21:55
This mini-thread clarified it for me, so I added my answer. Tracking subexpressions wouldn't solve the problem anyway, when using the ?: operator for example. –  Michael Donohue Jul 22 '09 at 22:43
show 1 more comment

If you break the line into multiple lines instead of making several method calls on one line, or if you set a breakpoint on that line and step through the line with a debugger, you can figure out which reference is null pretty easily.

share|improve this answer
add comment



then I suggest:

  1. Breaking up that line into more than one line and assign the possible NullPointerException-generating values to temporary variables.
  2. Use a debugger and step over each method call until you find the one causing the problem.
share|improve this answer
add comment

If narrowing things down to a single line isn't enough, I'd say something is wrong with your code. How many references do you typically have on a single line? Is it really that difficult to choose from among the objects you've got?

Like Grant Wagner said, a quick pass through a debugger should make it clear.

But don't ignore the issue if it's hard to figure out. It might be a hint that your code is badly written and needs refactoring.

share|improve this answer
Having an identifier would very likely eliminate the need to start the debugger at all. –  Michael Donohue Jul 22 '09 at 21:59
Usually inspection does it for me, because I don't have any lines of code with more than a few objects being dereferenced. –  duffymo Jul 22 '09 at 23:55
add comment

This is unfortunately just the way Java works.

If this is "your" code then simply add snippets like

if (foo == null) {
  throw new NullPointerException("foo == null");

right after assigning foo. If foo is a parameter then check immediately at the start of the method body, and throw IllegalArgumentException instead.

This should help you clarify matters.

share|improve this answer
I think assert statements would be preferable over if statements here. –  kpozin Jul 22 '09 at 22:44
Asserts are disabled by default. Not good. –  Thorbjørn Ravn Andersen Jul 22 '09 at 22:50
I would murder anybody who came into a code review with code like this. –  duffymo Jul 22 '09 at 23:58
@duffymo, if the code had failed in production? Interesting... –  Thorbjørn Ravn Andersen Jul 23 '09 at 6:52
@Thorbjorn I believe the use of NullPointerException by user code is frowned upon. It's meant to be thrown by the JRE. –  Michael Donohue Jul 23 '09 at 12:05
show 1 more comment

You can add a breakpoint on the null pointer exception in Eclipse when debugging to get the exact cause of the exception.

share|improve this answer
add comment

Your Answer


