How to Handle NullPointerException using Java
Tags: java, functional, programming
Published: 2021-10-04 20:03:16

If you use Java as your primary programming language, you've come across a NullPointerException at some point in your life. At a very high level, a NullPointerException is a RuntimeException that happens when you try to access a variable, but this variable is pointing to no object, and it's referring to nothing (or null). 

Take a look at the code snippet below:

```
public class Country {

    public static void main(String[] args) {

        String[] countries = new String[5];

        String asianCountry = countries[3].toUpperCase();
        System.out.println(asianCountry);
    }
}
```
What we get is:
```
Exception in thread "main" java.lang.NullPointerException
	at Country.main(Country.java:7)
```
We're getting a NullPointerException because we have a String array of countries, and we're trying to access its third element, which is *null*. 

There are some alternative ways that we can use to handle the NullPointerException, such as surrounding the code in a try/catch block (like in exampleOne) or if statements (like in exampleTwo). 

```
public class Country {

    public static void main(String[] args) {
        
        String country = "India";
        exampleOne(null);
        exampleTwo(null);

    }

    static void exampleOne(String country){
        try {
            System.out.println("Printing the country using try/catch: " + country.toUpperCase());
        } catch(NullPointerException e){
            System.out.println("Throwing a NullPointerException");
        }
    }

    static void exampleTwo(String country){
        if(country != null){
            System.out.println("Printing the country using IF/ELSE statement: " + country.toUpperCase());
        } else {
            System.out.println("There is no such country");
        }
    }
}

```
Outcome:
```
Throwing a NullPointerException
There is no such country
```

But this way, we're just making the code unpleasant to read. Plus, what if we have to check more data? The code would become more verbose. 

Java 8 has introduced the **Optional class** in the  [_ Java.util_](https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html)  package, which functions like a box that may or may not contain null values. 

#### What are the benefits of using this class? ####

1. At runtime, we won't get a NullPointerException.  🙌🏾
2. We don't have to carry out null checks. 🙌🏾
3. We reduce boilerplate code. 🙌🏾
4. We get to develop tidier APIs. 🙌🏾

The example above can be rewritten like this using the Optional class.
```
import java.util.Optional;

public class Country {

    public static void main(String[] args) {

        String[] countries = new String[5];

        Optional<String> checkCountry = Optional.ofNullable(countries[3]);

        if(checkCountry.isPresent()){
            String country = countries[3].toUpperCase();
            System.out.println(country);
        } else {
            System.out.println("The country is null");
        }
        
    }
}

```
- We created a String Optional that corresponds to the third country in the string array.
- The ofNullable() method returns an Optional with that value if it exists. Otherwise, it returns an empty Optional.
- In the IF/ELSE block, we're seeing if the country is present in the Optional or not. If it is, we print out the country in uppercase. Otherwise, we print a message to say that "The country is null." 

Since we haven't initialized the String array, the output would be:
```
The country is null
```
Otherwise, we can initialize the variable like here:
```
import java.util.Optional;

public class Country {

    public static void main(String[] args) {

        String[] countries = new String[5];
        countries[3] = "India";

        Optional<String> checkCountry = Optional.ofNullable(countries[3]);

        if(checkCountry.isPresent()){
            String country = countries[3].toUpperCase();
            System.out.println(country);
        } else {
            System.out.println("The country is null");
        }

    }
}
```
And the output would be:
```
INDIA
```
#### When is it best to use the Optional class? ####

✅ At return type

✅ Combined with  [Streams](https://techwithmaddy.com/java-8-streams) 

#### When should we avoid using the Optional class? ####

❌We shouldn't use it as a private field because it's not serializable (meaning that we wouldn't be able to transform that object into a format that we can store in the memory). 

❌ In method parameters or constructors: we would make the code more complicated to read.

It's critical to highlight that Optional is not a way to avoid all types of null checks. For example, you'll still need to think about the inputs taken in constructors and methods.  

I hope that you've found this helpful. Optional is an exciting addition, but be careful not to overuse it as it may potentially kill off its benefits! 😊