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 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]?

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, or k has type Integer 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.