Best practices to avoid NullPointerException in Java
In this tutorial, we will discuss the best practices to avoid or handle NullPointerException
in Java. NullPointerException
generally threw when we attempt to use null where an object is required. It can occur for many reasons like:
Hey! don’t be sad, you are not alone. Every Java developer has faced this problem in his/her career.
- 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.
- etc, etc.
NullPointerException
is a runtime exception and belongs to java.lang
package. It extends the RuntimeException
and available since JDK 1.0 version. Let’s see the hierarchy of NullPointerexception
:
1. java.lang.NullPointerException
Let’s create a scenario which throws the NullPointerException
:
package org.websparrow.exception;
public class NPEDemo {
public static void main(String[] args) {
Employee prince = null;
System.out.println(prince.details());
}
}
class Employee {
public String details() {
return "Name: Prince, Salary: 55K";
}
}
Output:
Exception in thread "main" java.lang.NullPointerException
at org.websparrow.exception.NPEDemo.main(NPEDemo.java:8)
1.1 What happens here?
There is a question that comes in your mind, what exactly happens here and why it throws the NullPointerException
? So the answer is whenever we try to use or access an object reference which has a null value, NullPointerException
will be thrown. Here the object of Employee
class is null and details()
method is called on a null reference in a case where an object reference is required that’s why it throws the NullpointerException
.
2. How to handle NullPointerException?
In Java, NullPointerException
can be handled or avoided in many ways.
2.1 The old way
If the application running on JDK <= 7 versions, we have to check it via the old way (the traditional style → using if-else…).
if (prince != null) {
String princeDetail = prince.details();
if (princeDetail != null) {
System.out.println(princeDetail.toLowerCase());
}
}
This is preventive code and definitely handle the NullPointerException
but it’s a bad coding style and it also increases the numbers of lines in the code.
2.2 The new way
JDK 8 introduces an Optional
utility class inside the java.util
package. Optional
is a wrapper which may or may not contains an object, and avoid null uses.
Optional<Employee> optionalPrince = Optional.ofNullable(prince);
if (optionalPrince.isPresent()) {
String princeDetail = optionalPrince.get().details();
Optional<String> optionalPrinceDetail = Optional.ofNullable(princeDetail);
if (optionalPrinceDetail.isPresent()) {
String detail = optionalPrinceDetail.get().toLowerCase();
System.out.println(detail);
}
}
There are no big differences between the old way and the new way, except for uses of Optional
. It is safe but still ugly and omission-prone.
2.3 Java 8 Optional and Functional Interfaces
Let’s use the functional interfaces and get more power from Optional
.
Optional<String> optionalPrince = Optional.ofNullable(prince).map(d -> d.details());
optionalPrince.ifPresent(s -> System.out.println(s.toLowerCase()));
Now it is much prettier and safe, even we can use method reference as shown below:
Optional<String> optionalPrince = Optional.ofNullable(prince).map(Employee::details);
optionalPrince.ifPresent(System.out::println);
3. Conclusion
By using Optional
, and never working with null, we could avoid null checks altogether.