Understanding and Handling NullPointerException in Java: Tips and Tricks for Effective Debugging


In this tutorial, we will see,

  1. Introduction to NullPointerException in Java
  2. Let's define NullPointerException
  3. Understanding "null" in Java and how it relates to NullPointerExceptions
  4. Best Practices to handle NullPointerException
  5. How to effectively debug NullPointerException and Fix it.
  6. Debugging using IDE IntelliJ/VS Code/Eclipse

1. Introduction to NullPointerException in Java

    NullPointerException in Java Programming Langauge is by far the most common type of exception that any developer may come across.

    It doesn't matter if you are a student learning Java or an expert with 10+ years in Java Programming, everyone has to deal with the prominent NullPointerException.

    Trust me! NullPointerException is the easiest exception to find and fix.

    Before we deep dive into this topic, first let us see some examples of these exceptions stack traces.


    Exception in a Simple Java Application:
    Exception in thread "main" java.lang.NullPointerException
    	at org.example.NPE.main(NPE.java:8)

    Exception in an Android Application:
    03-01 2023 12:12:00.291: E/AndroidRuntime(11975): FATAL EXCEPTION: main
    03-01 2023 12:12:00.291: E/AndroidRuntime(112782): java.lang.RuntimeException: 
    Unable to start activity com.testing.ringer/org.code2care.MainActivity: java.lang.NullPointerException
    03-01 2023 12:12:00.291: E/AndroidRuntime(112782): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1872)
    ..
    03-01 2023 12:12:00.291: E/AndroidRuntime(11975): at dalvik.system.NativeStart.main(Native Method)
    03-01 2023 12:12:00.291: E/AndroidRuntime(11975): Caused by: java.lang.NullPointerException

    Stack trace of a Spring Boot Application with NullPointerException:
    2022-01-05 02:48:10.673 [main] ERROR org.springframework.boot.SpringApplication 
    >>> Application run failed ||| org.springframework.context.ApplicationContextException: 
    Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException
     at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:181)
    ..
    Caused by: java.lang.NullPointerException: null
        at springfox.documentation.spi.service.contexts.Orderings$8.compare(Orderings.java:112)
        at springfox.documentation.spi.service.contexts.Orderings$8.compare(Orderings.java:109)
       

In all three stack traces you can see that the applications failed due to NullPointerException.


2. Let's define NullPointerException

    Looking at the stack traces above, one thing that you must have noticed.

    1) Exception in thread "main" java.lang.NullPointerException
    2) Caused by: java.lang.NullPointerException
    3) Caused by: java.lang.NullPointerException: null

    Looking at the exception, you can easily guess that NullPointerException is a Class file that resides in java.lang package. As a student or an investigator (debugger/bug fixer whatever you may call it) its always a good habit to get into the Class that caused the exception and read the code documentation.

    Assuming that you are using an IDE to code like Eclipse or IntelliJ, you can simply click on java.lang.NullPointerException hyperlink in the console and get to it. Below is a gif to demonstrate the same in IntelliJ

    Looking at the NullPointerException Class

    Let's look at the Class level documentation.

    /**
     * Thrown when an application attempts to use null in a
     * case where an object is required. These include:
     * 
     * - Calling the instance method of a null object.
     * - Accessing or modifying the field of a null object.
     * - Taking the length of null as if it were an array.
     * - Accessing or modifying the slots of null as if it were an array.
     * - Throwing null as if it were a Throwable value.
     *
     * @author  unascribed
     * @since   JDK1.0
     */
    public
    class NullPointerException extends RuntimeException {

    There is so much information here! Let's break them down.

    • You would notice that NullPointerException is of type RuntimeException.
    • Get into the RuntimeException class and you would know more about them in the class-level docs.
      • RuntimeException are thrown during the normal operation of the Java Virtual Machine.
      • RuntimeException and its subclasses are unchecked exceptions
    • So, NullPointerException is a unchecked exception as well.

    Definition of NullPointerException as per java.lang.NullPointerException class

    โœ๏ธ Thrown when an application attempts to use null in a case where an object is required.

    If you are unable to locate NullPointerException.java class, see it on GitHub:

    https://github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/java/lang/NullPointerException.java


3. Understanding "null" in Java and how it relates to NullPointerExceptions.

    When an Object in java does not point to any Object reference, it is said to be null. Let's understand this by an example,

    package org.example;
    
    /**
     * A simple Java Code
     * to demonstrate null
     */
    public class UnderstandingNull {
        //String Object is not referencing to any Object => null
        static String name;
    
        public static void main(String[] args) {
            System.out.println(name);
        }
    }
    
    Output:

    null


    Let us see another example, this time we have a custom class and a method call that returns a null.

    package org.example;
    
    /**
     * A simple Java Code
     * to demonstrate null
     * using Custom Class
     * and method call.
     */
    public class UnderstandingNull {
    
        public static void main(String[] args) {
            Dog myDog = new Dog();
            System.out.println("Dog's Name : "+ myDog.getDogName());
            System.out.println("Dog's Bark : "+myDog.getDogsBark());
        }
    
    
    }
    
    class Dog {
    
        private String dogName;
        private String dogsBark = "Woof";
    
        public String getDogName() {
            return dogName;
        }
    
        public String getDogsBark() {
            return dogsBark;
        }
    
    }
    
    Output:

    Dog's Name : null
    Dog's Bark : Woof

    Here in both cases, the object is of type String (name and dogName) and they do not point to any object reference, hence we have null as result.

    Now this should be clear! as per the definition when we try to access or modify the field of a null object we get NullPointerException.

    How do we use an Object?

    Coming back to basics, everything in Java is Classes and Objects, you can create runtime objects from a class using the new keyword. Each object has its own attributes (variables) and behavior (methods), and you can access or manipulate the attributes of the object by calling the behaviors (methods)

    So the way we "use" objects is by calling their methods.

    What if the Object is null and we call its methods?

    Well! that is how you get a NullPointerException!

    Example:

    1. package org.example;
    2. 
    3. public class UnderstandingNullPointerException {
    4. 
    5.    public static void main(String[] args) {
    6.        Dog myDog = null;
    7.        System.out.println("Dog's Name : "+ myDog.getDogName());
    8.    }
    9.
    10. }
    11. 
    12. class Dog {
    13. 
    14.    private String dogName ="Thomas";
    15.    private String dogsBark = "Woof";
    16.
    17.    public String getDogName() {
    18.        return dogName;
    19.    }
    20.
    21.    public String getDogsBark() {
    22.        return dogsBark;
    23.    }
    24. 
    25. }
    
    Output:

    Exception in thread "main" java.lang.NullPointerException
       at org.example.UnderstandingNullPointerException.main(UnderstandingNullPointerException.java:7)

    Look at line number 6, clearly we have created an object of the Dog class that is pointing to null.

    Now on line number 7, we are "making use" (acting) on the object by calling its methods, which is null, thus NullPointerException.


4. Best Practices to handle NullPointerException

    As we saw, NullPointerException is a RuntimeException, and for such exceptions, it is the developer who is using the Object needs to make sure to check if the object that he/she is dealing with is null or not before use.

  • Make sure to check the object reference for null value before using it.

    Example: How to check for null value using if condition

        public static void main(String[] args) {
            Dog myDog = new Dog();
            
            if(myDog == null) {
                System.out.println("Error! The Dog object is null!");
            } else {
                System.out.println("Dog's Name : " + myDog.getDogName());
            }
        }

    Example: How to check for null value using Java 8 Optional class

        public static void main(String[] args) {
    
            Dog myDog = null;
    
            if(Optional.ofNullable(myDog).isPresent()) {
                System.out.println("Dog's Name : " + myDog.getDogName());
            } else {
                System.out.println("Error! Dog Object is null!");
            }
        }

    Example: Using the isNull() method from Objects class

        public static void main(String[] args) {
    
            Dog dog = null;
    
            if (Objects.isNull(dog)) {
                System.out.println("Dog object is null");
            }
        }
  • Remember to initialize object references before use, you may also assign a default value of null.

  • Example:
        public static void main(String[] args) {
            
            Dog dog = new Dog();
            System.out.println(dog.getDogsBark());
        }
  • The IDE is of great help, if you are using Eclipse, VS Code, or IntelliJ, make sure to keep an eye on all the warnings a particular class is giving for a potential NullPointerExceptions.
  • Method invocation getDogsBark will produce NullPointerException

    As you may see in the above screenshot, the IntelliJ IDE is giving me a hint/warning that the method invocation 'getDogsBark' will produce 'NullPointerException' as the object reference of Dog is null.

  • Peer review/Code reviews can really help to catch NullPointer Exceptions before they reach production.

    โœ‹๏ธ It is highly recommended to install the Sonar Lint plugin to do a self-code review.

5. How to effectively debug NullPointerException and Fix it.

    1. The first thing to do is to look at the stack trace and location where the NullPointerException has occurred.
    2. Look for the null reference in the code, you will mostly get the line number and the Class from the Strack trace just after "Caused by NullPointerException ... " just the class after first at
    3. Now surround the code with an if condition to check the object reference is not null.
    4. If null, give an appropriate error message.

    Let us see these steps with Example:

    Example:
    1. package org.example;
    2. public class UnderstandingNullPointerException {
    3.    static String name;
    4.    public static void main(String[] args) {
    5.        System.out.println(name.toUpperCase());
    6.    }
    7. }
Output:
Exception in thread "main" java.lang.NullPointerException
	at org.example.UnderstandingNullPointerException.main(UnderstandingNullPointerException.java:5)
  • Step 1: Look at the stack trace we see NullPointerException has occurred.
  • Step 2: Look at the class name after first "at" i.e. UnderstandingNullPointerException.java, also note the line no. 5
  • Step 3 & 4: Go to the class and the line number to locate the Object with null reference - it is name in our case. Let us surround it with if condition null check.
    if(name == null) {
       System.out.println("Error! Name is null and not defined!");
    } else {
       System.out.println(name.toUpperCase());
    }

6. Debugging using IDE IntelliJ/VS Code/Eclipse

We have seen a lot of IntelliJ, let's see an example with Eclipse now. Run the code in Debug mode by clicking on the debug button, before that make sure to add a breakpoint at the line where the NPE has occurred.

Debugging NullPointerException in Eclipse IDE

As you would see in the above gif demo when I add a breakpoint at line 10 and inspect the String object name, its value is null.

References

- https://docs.oracle.com/javase/7/docs/api/java/lang/NullPointerException.html

Facing issues? Have Questions? Post them here! I am happy to answer!

Author Info:

Rakesh (He/Him) has over 14+ years of experience in Web and Application development. He is the author of insightful How-To articles for Code2care.

Follow him on: X

You can also reach out to him via e-mail: rakesh@code2care.org



















Copyright ยฉ Code2care 2024 | Privacy Policy | About Us | Contact Us | Sitemap