One of the important features that were introduced with Java SE 14 was the Helpful NullPointerExceptions which is related to the usability of the NullPointerException
. What makes NullPointerException
in Java SE 14 more usable than its predecessor?
What Causes NullPointerException. The NullPointerException occurs due to a situation in application code where an uninitialized object is attempted to be accessed or modified. Essentially, this means the object reference does not point anywhere and has a null value.
The NullPointerException (NPE) typically occurs when you declare a variable but did not create an object and assign it to the variable before trying to use the contents of the variable. So you have a reference to something that does not actually exist. Take the following code: Integer num; num = new Integer(10);
NullPointerException is a runtime exception and it is thrown when the application try to use an object reference which has a null value. For example, using a method on a null reference.
Java 14 – Helpful NullPointerException (NPE) Java 14 (JEP 358) improves the usability of NullPointerException generated by the JVM by describing precisely which variable was null. Lets understand this in detail. 1.
JEP 358 brings a detailed NullPointerException message by describing the null variable, alongside the method, filename, and line number. It works by analyzing the program's bytecode instructions. Therefore, it's capable of determining precisely which variable or expression was null.
Java 14 ( JEP 358) improves the usability of NullPointerException generated by the JVM by describing precisely which variable was null. Lets understand this in detail. 1. Better NullPointerException First, we need to pass -XX:+ShowCodeDetailsInExceptionMessages JVM flag to enable this feature while running the application.
Null is a special value used in Java. It is mainly used to indicate that no value is assigned to a reference variable. One application of null is in implementing data structures like linked list and tree. Other applications include Null Object pattern (See this for details) and Singleton pattern.
The JVM throws a NullPointerException
at the point in a program where code tries to dereference a null
reference. With Java SE 14, the NullPointerException
offers helpful information about the premature termination of a program. Java SE 14 onwards, the JVM describes the variable (in terms of source code) with a null-detail message in the NullPointerException
. It greatly improves program understanding by more clearly associating a dynamic exception with static program code.
We can see the difference with an example.
import java.util.ArrayList;
import java.util.List;
class Price {
double basePrice;
double tax;
public Price() {
}
public Price(double basePrice) {
this.basePrice = basePrice;
}
public Price(double basePrice, double tax) {
this.basePrice = basePrice;
this.tax = tax;
}
// ...
}
class Product {
String name;
Price price;
public Product() {
}
public Product(String name, Price price) {
this.name = name;
this.price = price;
}
// ...
}
class CartEntry {
Product product;
int quantity;
public CartEntry() {
}
public CartEntry(Product product, int quantity) {
this.product = product;
this.quantity = quantity;
}
// ...
}
class Cart {
String id;
List<CartEntry> cartEntries;
public Cart() {
cartEntries = new ArrayList<>();
}
public Cart(String id) {
this();
this.id = id;
}
void addToCart(CartEntry entry) {
cartEntries.add(entry);
}
// ...
}
public class Main {
public static void main(String[] args) {
Cart cart = new Cart("XYZ123");
cart.addToCart(new CartEntry());
System.out.println(cart.cartEntries.get(0).product.price.basePrice);
}
}
Exception in thread "main" java.lang.NullPointerException
at Main.main(Main.java:74)
This message leaves the programmer clueless about the source of the NullPointerException
.
Exception in thread "main" java.lang.NullPointerException: Cannot read field "price" because "java.util.List.get(int).product" is null
at Main.main(Main.java:74)
The NullPointerException
in Java SE 14 also tells us which reference is null
.
A great improvement!
It is documented in the release notes.
The new message is not being displayed by default in version 1.14:
What's new in JDK 14
A new option is available to provide more helpful NullPointerException messages:
-XX:+ShowCodeDetailsInExceptionMessages
If the option is set, on encountering a null pointer, the JVM analyzes the program to determine which reference was null and then provides the details as part of NullPointerException.getMessage(). In addition to the exception message, the method, filename, and line number are also returned.
By default, this option is disabled.
and the full proposal JEP 358 for motivation.
Eventually
What's new in JDK 15
The default of the flag ShowCodeDetailsInExceptionMessages was changed to 'true'.
When the JVM throws a NullPointerException
, it now adds a detail message that specifies which reference was null.
This makes the stack trace easier to interpret, and resolves ambiguity if the program accesses several references on the same line in the source code. For instance, the line
person.name = student.name;
throws a NullPointerException
if person
or student
is null
, but prior to Java 14, the exception didn't tell us which one it was. Now, it does:
java.lang.NullPointerException: Cannot read field "name" because "student" is null
Further information about this change is available in JEP-358.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With