Helpful null pointer exception messages now standard in Java 21
In the old days of Java, null pointer exceptions came with exception messages that were often null themselves. That was annoying.
Sometimes it was easy to work through the stack trace and figure out what it was that you forgot to initialize. Such as for example, if a null pointer exception occurs early in a constructor, it’s very likely that the problem is due to a null constructor parameter.
When a null pointer exception happens outside of a constructor, it might not be so easy to figure out what the problem is. The authors of Java Enhancement Proposal JEP-358 give a couple of examples where it’s not so clear what was null.
In one example,
a.b.c.i = 99;
it’s not clear if it’s c
or b
that was null. Presumably it’s not a
that’s null here.
Multidimensional arrays can also make it difficult to pinpoint the reason for a null pointer exception.
a[i][j][k] = 99;
In my extensive experience with Java 8, I frequently wrote unit tests that deliberately pass null parameters to constructors and test that the resulting null pointer exception has a non-null exception message.
Now that I have moved on to Java 21, I still write such unit tests. But I was quite surprised to see how helpful the null pointer exception messages are now.
Cannot invoke “java.util.Currency.getDefaultFractionDigits()” because “currency” is null
JEP-358 was enacted in Java 14, but that was not a long-term support (LTS) release. Java 17 was LTS, but it wasn’t until Java 21 that I upgraded from Java 8.
I think it is still worthwhile to write unit tests for null pointer exceptions that you can foresee. But your strategy for writing the unit tests will be different.
Maybe in test-driven development (TDD), you write a stub that throws some irrelevant exception for null parameters. It fails the test, so then you get that test to pass by deleting the line that throws the irrelevant exception.