How to avoid Null Checks in Java 8

How to prevent the famous NullPointerException in Java? This is most important topic for interview. Anyways, we have to deal with Null pointer exception. So what can we do to prevent NullPointerExceptions at all? The obvious answer is to add null checks all around the place. Since null checks are painful to add every place.

Java 8 introduced an Optional class which is a nicer way to avoid NullPointerExceptions. You can use Optional to encapsulate the potential null values and pass or return it safely without worrying about the exception. Without Optional, when a method signature has return type of certain object.
Improving Null Safety in Java 8 : We can utilize the Optional type of Java 8 to prevent null checks. We have the object hierarchy structure.
class Employee {
    Address address;
    String name;
    Address getAddress() {
        return address;
    }

}
class Address {
    String city;
    Address(String city)
    {
        this.city=city;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }
}

In below examples are showing how can put multilevel null checks without Optional. To resolving and avoiding null in nested object we have to put lots of checks to resolving the NullPointerException in code logic.

public class Java8NullChecks1 {

    public static void main(String[] args) {
        Employee employee=new Employee();
        employee.name="Joy";
        employee.address=new Address("Delhi");
        if(employee!=null && employee.address!=null)
        {
            System.out.println(employee.name+" From "+employee.address.city);
        }
    }

}

We can get rid of all those null checks by utilizing the Java 8 Optional type. The method map accepts a lambda expression of type Function and automatically wraps each function result into an Optional. That enables us to pipe multiple map operations in a row. Null checks are automatically handled under the hood.


Optional.of(employee).map(Employee1::getAddress).map(Address::getCity).
                ifPresent(System.out::println);

An alternative way to achieve the same behavior is by utilizing a supplier function to resolve the nested path:

resolve(() -> employee.getAddress().getCity()).ifPresent(System.out::println);

And above method might trough the null exception but we handle in supplier method by using try and catch block.

    static <T> Optional<T> resolve(Supplier<T> supplier){

        try {
             T result=supplier.get();
             return  Optional.ofNullable(result);
        }catch (NullPointerException e){
            return Optional.empty();
        }

    }



No comments:

Post a Comment