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()