Search code examples
javanullpointerexceptionjava-14

How is NullPointerException in Java 14 different from its predecessor?


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?


Solution

  • 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);
        }
    }
    

    Output before Java SE 14:

    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.

    The output with Java SE 14 onwards:

    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!