JEP 358: Helpful NullPointerExceptions
Summary
Improve the usability of NullPointerException
s generated by the JVM by describing precisely which variable was null
.
Goals
-
Offer helpful information to developers and support staff about the premature termination of a program.
-
Improve program understanding by more clearly associating a dynamic exception with static program code.
-
Reduce the confusion and concern that new developers often have about
NullPointerException
s.
Non-Goals
-
It is not a goal to track down the ultimate producer of a
null
reference, only the unlucky consumer. -
It is not a goal to throw more
NullPointerException
s, or to throw them at a different point in time.
Motivation
Every Java developer has encountered NullPointerException
s (NPEs). Since NPEs can occur almost anywhere in a program, it is generally impractical to attempt to catch and recover from them. As a result, developers rely on the JVM to pinpoint the source of an NPE when it actually occurs. For example, suppose an NPE occurs in this code:
a.i = 99;
The JVM will print out the method, filename, and line number that caused the NPE:
Exception in thread "main" java.lang.NullPointerException
at Prog.main(Prog.java:5)
Using the message, which is typically included in a bug report, the developer can locate a.i = 99;
and infer that a
must have been null. However, for more complex code, it is impossible to decide which variable was null without using a debugger. Suppose an NPE occurs in this code:
a.b.c.i = 99;
The filename and line number do not pinpoint exactly which variable was null. Was it a
or b
or c
?
A similar problem occurs with array access and assignment. Suppose an NPE occurs in this code:
a[i][j][k] = 99;
The filename and line number do not pinpoint exactly which array component was null. Was it a
or a[i]
or a[i][j]
?
A single line of code may contain several access paths, each one potentially the source of an NPE. Suppose an NPE occurs in this code:
a.i = b.j;
The filename and line number do not pinpoint the offending access path. Was a
null, or b
?
Finally, an NPE could stem from a method call. Suppose an NPE occurs in this code:
x().y().i = 99;