NullPointerExceptions will be awesome in JDK 14

NullPointerExceptions probably are the most popular exceptions faced by any Java developer. As a class, NullPointerException has been in Java since version 1.0 and wasn’t updated after that.

With JDK 14 comes JEP 358 aimed at improving this particular exception. And judging by the enormous amount of frustration NPE has caused developers, this update is a long-awaited one.

Let’s analyze what’s wrong with current NPEs and explore the improvements done in JDK 14 in that front.

Usually, when NPE is thrown, it contains a handy stack trace, pointing to the root cause. In a simplified scenario, stack trace might look like this:

1
2
Exception in thread "main" java.lang.NullPointerException
 at com.company.VeryImportantBank.main(VeryImportantBank.java:9)

From this, we could take a look at VeryImportantBank class on line 9 and the root cause for the exception is pretty obvious:

1
bankAccount.addSomeMoney();

the object bankAccount is null. In simple scenarios, NPE is giving enough information to pinpoint the problem, but in real-life applications, this scenario is quite rare. Most often, developers deal with much more complex code. For example, the 9th line of VeryImportantBank class might look like this:

1
2

bankAccount.addSomeMoney(customer.getCheckingAccount().getMoney());

and if any of the variables is null, then the same exception will be thrown, pointing to line number 9:

1
2
Exception in thread "main" java.lang.NullPointerException
 at com.company.VeryImportantBank.main(VeryImportantBank.java:9)

Which isn’t that helpful, right? The filename and line number is not enough to pinpoint the problem. It would be awesome to know what exactly is null. And JEP 358 accomplishes exactly that! Take a look at the same code, run on JDK 14 with -XX:+ShowCodeDetailsInExceptionMessages flag (because it’s not enabled by default yet in early access build of JDK 14):

1
2
3
4
Exception in thread "main" java.lang.NullPointerException: 
    Cannot invoke "com.company.VeryImportantBank$Customer.getCheckingAccount()" 
        because "com.company.VeryImportantBank.customer" is null
         at com.company.VeryImportantBank.main(VeryImportantBank.java:9)

👏👏👏 Now the detail message of NPE provides enough information to fix the problem without second-guessing.

JEP 358 is a very straightforward enhancement that will provide enormous value to Java developers on a daily basis.