About NewTechnoBuzz
Advertise
Contact Us

Tuesday, August 5, 2014

How to avoid NullPointerException in Java

In Java, a special null value can be assigned to an object’s reference and denotes that the object is currently pointing to unknown piece of data. A NullPointerException is thrown when an application is trying to use or access an object whose reference equals to null.

NullPointerException is an unchecked exception and extends RuntimeException. It doesn’t force you to use catch block to handle it. NullPointerException is very much like a nightmare for most of java developer community. They usually pop up when you least expect them.

By applying some defensive coding techniques between multiple part of application, you can avoid NullPointerException in Java to a good extent. In this tutorial, we will learn some Java coding techniques and best practices, which can be used to avoid NullPointerException in Java.

Why do we need null value?

As already mentioned, null is a special value used in Java. It is extremely useful in coding some design patterns, such as Null Object pattern and Singleton pattern. The Null Object pattern provides an object as a surrogate for the lack of an object of a given type. The Singleton pattern ensures that only one instance of a class is created and also, aims for providing a global point of access to the object.

Why NullPointerException occurs

NullPointerException is a situation in code where you try to access/ modify an object which has not been initialized yet. It essentially means that object reference variable is not pointing anywhere and refers to nothing or ‘null’. A simple example can be:

public class Demo {
    public static void main(String[] args) {
        String s = null;
        System.out.println(s.toString()); //s is un-initialized and is null
    }
}

The following cases throw that exception:
  • Invoking a method from a null object.
  • Accessing or modifying a null object’s field.
  • Taking the length of null, as if it were an array.
  • Accessing or modifying the slots of null object, as if it were an array.
  • Throwing null, as if it were a Throwable value.
  • When you try to synchronize over a null object.

Best practices to avoid NullPointerException

These are simple techniques, which is very easy to follow, but has significant impact on code quality and robustness.

1. Prefer String.valueOf() method instead of toString()

When your application requires the String representation of an object, then avoid using the object’s toString method because if your object’s reference is null, then a NullPointerException will be thrown. Instead, use String.valueOf method, which does not throw any exceptions and prints "null", in case the function’s argument equals to null.

BigDecimal price = getPrice();
System.out.println(String.valueOf(price)); //doesn’t throw NPE
System.out.println(price.toString()); //throws "Exception in thread "main" java.lang.NullPointerException"

2. Call equals() and equalsIgnoreCase() method on known String literal rather unknown object

Always call equals() method on known String which is not null. Since equals() method is symmetric, calling a.equals(b) is same as calling b.equals(a), and that’s why many programmer don’t pay attention on object a and b. One side effect of this call can result in NullPointerException, if caller is null.

String str = null;
if(str.equals("Test")) {
     /* The code here will not be reached, as an exception will be thrown. */
}

The above code snippet will throw a NullPointerException. However, if we invoke the method from the literal, the execution flow continues normally:

String str = null;
if("Test".equals(str)) {
     /* Correct use case. No exception will be thrown. */
}

3. Check the arguments of a method

Before performing any operation on the arguments of a method, be sure to check its arguments for null values. Continue with the execution only when the arguments are properly checked. Otherwise, you can throw an IllegalArgumentException and notify the calling method that something wrong with the passed arguments.

public static int getLength(String str) {
     if (str == null)
          throw new IllegalArgumentException("The argument cannot be null");
     return str.length();
}

4. Avoid returning null from method, instead return empty collection or empty array.

A very good technique is to create methods that return an empty collection, instead of a null value. By returning empty collection or empty array you make sure that basic calls like size(), length() doesn't fail with NullPointerException. Collections class provides convenient empty List, Set and Map as Collections.EMPTY_LIST, Collections.EMPTY_SET and Collections.EMPTY_MAP which can be used accordingly.

public static int getLength(String str) {
     if (str == null)
          throw new IllegalArgumentException("The argument cannot be null");
     return str.length();
}
List<String> data = null;
 
@SuppressWarnings("unchecked")
public List getData()
{
    if(data == null)
        return Collections.EMPTY_LIST; //Returns unmodifiable list
    return data;
}


5. Use apache commons StringUtils for String operation

Apache commons lang is a collection of several utility classes for various kind of operations. One of them is StringUtils.java. Use StringUtils.isNotEmpty() for verifying if string passed as parameter is null or empty string. If it is not null or empty; then use it further. Other similar methods are StringUtils. IsEmpty(), and StringUtils.equals().

if (StringUtils.isNotEmpty(obj.getvalue())){
    String str = obj.getvalue();
    ....
}

6. Ternary Operator

This operator results to the value on the left hand side if not null else right hand side is evaluated. It has syntax like :
boolean expression ? value1 : value2;

If expression is evaluated as true then entire expression returns value1 otherwise value2. Its more like if-else construct but it is more effective and expressive. To prevent NullPointerException:
String str = (param == null) ? "NA" : param;

7. Use of annotation @NotNull and @Nullable

While writing method you can declare whether a method is null safe or not, by using annotations like @NotNull and @Nullable. Modern days compiler, IDE or tool can read this annotation and assist you to put a missing null check, or may inform you about an unnecessary null check, which is cluttering your code. By looking @NotNull and @Nullable, programmer can decide whether to check for null or not.

8. Avoid unnecessary autoboxing and unboxing in your code

We know that, autoboxing wraps the primitive value into a wrapper class. So, it is also prone to NullPointerException, if the wrapper class object is null.

9. Use Null Object Pattern

This is another way of avoiding NullPointerExcpetion in Java. If a method returns an object, on which caller, perform some operations e.g. Collection.iterator() method returns Iterator, on which caller performs traversal. Suppose if a caller doesn’t have any Iterator, it can return Null object instead of null. Null object is a special object, which has different meaning in different context, for example, here an empty Iterator, calling hasNext() on which returns false, can be a null object. Similarly in case of method, which returns Container or Collection types, empty object should be used instead of returning null. I am planning to write a separate article on Null Object pattern, where I will share few more examples of NULL objects in Java.

10. Exception Handling using try-catch block

Use of try-catch block is also one of the way to handle NullPointerException in Java.

String managerId = getManager("123"); 

try { 
  System.out.println(managerId.toString()); 
} catch (NullPointerException npe) { 
  //write your code here 
}

That's all from my side for this article. Please provide your valuable feedback and comments.


0 comments