Find out what variable is throwing a NullPointerException programmatically
Since it's possible to cause a null pointer exception without even involving a variable:
throw new NullPointerException();
I would have to say that there is no generic way to pin down a null pointer exception to a specific variable.
Your best bet would be to put as few as possible statements on each line so that it becomes obvious what caused the null pointer exception. Consider refactoring your code in the question to look something like this:
List items = this.superSL.items;
String name = items.get(name);
String source = name.getSource();
if (source.compareTo(VIsualShoppingList.Source_EXTRA) == 0) {
// ...
}
It's more lines of code to be sure. But it's also more readable and more maintainable.
You might consider, as announced here, the JDK 14 which should include the JEP 358:
JEP 358: Helpful NullPointerExceptions
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 ita
orb
orc
?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 ita
ora[i]
ora[i][j]
?Description:
If the more complex statement
a.b.c.i = 99;
throws an NPE, the message would dissect the statement and pinpoint the cause by showing the full access path which led up to the null:
Exception in thread "main" java.lang.NullPointerException:
Cannot read field "c" because "a.b" is null
at Prog.main(Prog.java:5)
Again: to be tested with JDK 14.
Holger adds in the comments:
For the expression
a[i][j][k]
, there’s also the possibility that either,i
,j
, ork
has typeInteger
and is null, so unboxing fails.In real life scenarios, the expression to the right of the
=
might bear potential for NPE too.I tried with jdk-14.0.1
it works; it produces a message like
Cannot invoke "java.lang.Integer.intValue()" because "i" is null then.
When the method has been compiled without debug information, it will use something like "
<local8>
" instead of "i
", but that’s unavoidable.