New JDK14 enhancement for NullPointException

JEP 358: Helpful NullPointerExceptions

There is an enhancement for NPE on JDK14, which shows precisely which variable in your project was null. Let’s see the original NPE message by an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class NPETest {

class SomeClass {
public SomeClass2 someClass2;
}

class SomeClass2 {
}

public static void main(String[] args) {
SomeClass someClass = null;
System.out.println(someClass.someClass2);
}
}

We have two classes SomeClass and SomeClass2 in the NPETest class. We just declare a variable called someClass in the main function. When you try to run this example, you would see the NullPointException in the console like this:

1
2
3
4
5
6
7
Exception in thread "main" java.lang.NullPointerException
at NPETest.main(NPETest.java:12)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.uiDesigner.snapShooter.SnapShooter.main(SnapShooter.java:58)

Now you can see it warns you that you have an NPE at line 12 in the NPETest.main function. In fact, We have no idea about which variable is null. Is someClass or someClass2 null? We need to add more logs to verify which one is null or both are null. It would take some time to debug. That’s the reason why this enhancement is fantastic. Let’s see when you switch to JDK14 and what the log looks like:

1
2
3
4
5
6
7
Exception in thread "main" java.lang.NullPointerException: Cannot read field "someClass2" because "someClass" is null
at NPETest.main(NPETest.java:12)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at com.intellij.uiDesigner.snapShooter.SnapShooter.main(SnapShooter.java:58)

It’s much better now. It points out that someClass is null, and this is the exact point that causes the NPE. It saves lots of time to debug. Let’s see how to enable this feature to help us.

Here is the IDE version I use to develop, and it supports JDK14.
IDE

In the project configuration, you also need to set up the VM option:

1
-XX:+ShowCodeDetailsInExceptionMessages

This option would enable the VM to give you more information about the NPE. It’s off by default. Please check the image below for more details:
VM

After doing all of these, you can enjoy the more precise information provided by VM. You might wonder why Java provides such useful enhancement so late (until JDK14). Before JDK14, you probably know Optional this keyword. It tries to let developers avoid the NPE. Here is an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class NPETest {

class SomeClass {
public SomeClass2 someClass2;
}

class SomeClass2 {
}

public static void main(String[] args) {
Optional<SomeClass> optional = Optional.empty();
SomeClass someClass = null;
if (optional.ofNullable(someClass).isPresent()) {
System.out.println(someClass.someClass2);
}
else {
System.out.println("null object");
}
}
}

We can check a variable beforehand to avoid a possible NPE. The drawback is we need to write more code for the check. The philosophy of JEP 358 is that if we can’t prevent NPE in a Java project, then we should show more details at least.

What about Kotlin?

Let’s see how Kotlin handles a possible null object.

1
2
var someClass: SomeClass? = null 
println(someClass.someClass2)

You would get a compiler error said you should use ? for a nullable variable.

1
Error:(16, 22) Kotlin: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type SomeClass?

It’s much smarter to let you know the error in advance. It is also one of the main reasons I would recommend that developers should try Kotlin. You would enjoy the benefits that Kotlin brings to you.

Reference

JEP 358: Helpful NullPointerExceptions