Lewis D.
The Problem
In Java, a NullPointerException
occurs when a variable that is being accessed has not yet been assigned to an object, in other words, the variable is assigned as null
.
If you have read the Sentry answer to Is Java Pass-By-Reference or Pass-By-Value?, you might know that in Java, variables are simply pointers to objects in memory. Therefore, a null pointer exception will occur when the code is pointing to something in memory that does not exist.
The Java API documentation on NullPointerException
lists a couple of scenarios where this exception could be invoked:
- 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.
The Solution
Let’s take a look at a concrete example of where a NullPointerException
might be thrown.
Consider the following code example:
class NullPointerExample {
private static void printFirstElement[String[] array] {
System.out.println[array[0]];
}
public static void main[String[] args] {
String[] myStringArray = null;
printFirstElement[myStringArray];
}
}
Executing this code will result in the following stack trace:
Exception in thread "main" java.lang.NullPointerException
at NullPointerExample.printFirstElement[NullPointerExample.java:6]
at NullPointerExample.main[NullPointerExample.java:11]
This happens because in our printFirstElement[]
method, we attempted to access the first element of an array which does not exist. Similarly, taking the length of this given array
would yield the same result. We could make this code null-safe by adding a check for null before attempting to access the first element:
class NullPointerExample {
private static void printFirstElement[String[] array] {
if [null != array]{
System.out.println[array[0]];
}
else{
System.out.println["The array was null!"];
}
}
public static void main[String[] args] {
String[] myStringArray = null;
printFirstElement[myStringArray];
}
}
Executing this code now will yield the following output:
The array was null!
This is one important technique we can use to avoid tumbling into a NullPointerException
during code execution. Some tips for avoiding a NullPointerException
include:
- Perform null checks to ensure that objects are correctly initialized before accessing any of the object’s methods.
- Use
primitives [where it makes sense] such as
int
,boolean
andchar
, as these cannot be assigned as null and therefore cannot cause aNullPointerException
. - When first initializing objects, attempt to assign default or temporary values to them.
- Use a tool like FindBugs, which performs static analysis of code and can detect
NullPointerException
issues before you actually execute any of your code. - Use a tool
like NullAway which acts on
@NotNull
and@Nullable
annotations.
Further Reading
Is Java Pass-By-Reference or Pass-By-Value?
Null Pointer Exception is a kind of run time exception that is thrown when the java program attempts to use the object reference that that contains the null value. The null pointer exception can be thrown in the following scenarios.
1. The method is invoked using a null object
Java program throws a NullPointerException if we invoke some method on the null object. Consider the following example.
Output:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "DummyClass.convert[String]" because "dummy" is null at DummyClass.main[DummyClass.java:14]
2. The program tries to modify the null object's field.
The null pointer exception can be thrown if we try to modify the field for a null object. Consider the following example.
Output:
Exception in thread "main" java.lang.NullPointerException: Cannot read field "num" because "dummy" is null at DummyClass.main[DummyClass.java:10]
3. Passing a null argument to the method
If we do not check the arguments of a method for the null values, the null pointer exception can occur. Consider the following example.
Output:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.toUpperCase[]" because "s" is null at DummyClass.convert[DummyClass.java:4] at DummyClass.main[DummyClass.java:9]
4. Tries to operate on the array object which is null
However, if we try to perform an operation on a null array, the null pointer exception will be thrown. Consider the following example.
Output:
Exception in thread "main" java.lang.NullPointerException: Cannot read the array length because "dummy.arr" is null at DummyClass.main[DummyClass.java:7]
5. Tries to synchronize over a null object.
When we try to synchronize the method or block for the concurrent access, we must check whether the object reference we use for the synchronization is null. Consider the following example.
Output:
Exception in thread "main" java.lang.NullPointerException: Cannot enter synchronized block because "DummyClass.var" is null at DummyClass.main[DummyClass.java:6]
Avoiding null pointer exception has been an important task for Java developers. Many programming languages provide methods to check null pointer exceptions. However, Java doesn't provide such methods.
To avoid Null pointer exceptions, we need to ensure that all objects are initialized with a legitimate value before using them. We must verify at the time of defining a reference variable that it is not null since performing any operations on a null reference variable leads to the null pointer exception.
There are the following scenarios that we need to consider while dealing with the null pointer exceptions.
String Comparisons
When we compare the strings to literals, there might be the case that we encounter a null pointer exception if the string object that we are comparing is null. Consider the following example.
Output:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.equals[Object]" because "str" is null at StringCompare.main[StringCompare.java:7]
The above example will give null pointer exceptions since the string object which calls the equals [] method is null. However, we can avoid such scenarios if we call the equals [] method on a String literal [whose value is already known] rather than a String object. Consider the following example, which doesn't give the null pointer exception.
Output:
Using Ternary operator
We can also use the ternary operator to avoid the null pointer exceptions. We can put the check using the ternary operator. We check the Boolean expression and return value 1 if the expression is true; otherwise, return value 2.
Consider the following example.
Output:
null value Javatpoint JTP
In the above example, if the string object is null, the msg will be a null value; otherwise, it will print the actual string.
Checking arguments of the method
We can check on the arguments of a method for null values before executing the body of the method. Consider the following example, which throws an IllegalArgumentException when the arguments passed in the method are not legitimate.
Output:
IllegalArgumentException caught 50