A NullPointerException in Java application is the best way to solve it and that
is also key to write robust programs that can work smoothly. As it said “prevention
is better than cure”, same is true with nasty NullPointerException. Thankfully
by applying some defensive coding techniques and the following contracts between
multiple parts of an application, you can avoid NullPointerException in Java to a
good extent. By the way, this is the second post on NullPointerException in
Javarevisited, In the last post, we have discussed the common
causes of NullPointerException in Java and in this tutorial, we will learn some Java coding techniques and
best practices, which can be used to avoid NullPointerException in Java.
Following these Java tips also minimize the number of !=null check,
which litter a lot of Java code. As an experienced Java programmer, you may be
aware of some of these techniques and already following it in your project, but
for freshers and intermediate developers, this can be good learning.
By the way, if you know any other Java tips to avoid NullPointerException and reduce null checks in Java, then please share it with us.
By the way, if you know any other Java tips to avoid NullPointerException and reduce null checks in Java, then please share it with us.
Java Tips and Best practices to avoid NullPointerException
These are simple techniques, which is very easy to follow but have a significant impact on code quality and robustness. In my experience, just first
tip is resulted in significant improvement in code quality. As I said earlier, if
you know any other Java tips or best practice, which can help to reduce null
check, then you can share with us by commenting on this article.
1. 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.
Object unknownObject = null;
//wrong way - may cause
NullPointerException
if(unknownObject.equals("knownObject")){
System.err.println("This may result in NullPointerException if unknownObject
is null");
}
//right way - avoid
NullPointerException even if unknownObject is null
if("knownObject".equals(unknownObject)){
System.err.println("better
coding avoided NullPointerException");
}
This is the easiest Java tip or best practice to avoid NullPointerException, but results in tremendous improvement, because of equals()being a common method. See Java Programming courses for beginners to learn more about the equals method and other essential Java concepts.
2. Prefer valueOf() over toString() where both return same result
Since calling toString() on null
object throws NullPointerException, if we can get same value
by calling valueOf()
then prefer that, as passing null to valueOf() returns "null",
specially in case of wrapper classes
like Integer, Float, Double or BigDecimal.
BigDecimal bd = getPrice();
System.out.println(String.valueOf(bd)); //doesn’t
throw NPE
System.out.println(bd.toString()); //throws
"Exception in thread "main" java.lang.NullPointerException"
Follow this Java tips, if you are unsure about object being null or not.
3. Using null safe methods and libraries
There are lot of open source library out there, which does the heavy
lifting of checking null for you. One of the most common one is StringUtils from Apache commons. You can use StringUtils.isBlank(), isNumeric(), isWhiteSpace() and other
utility methods without worrying of NullPointerException.
//StringUtils methods are null
safe, they don't throw NullPointerException
System.out.println(StringUtils.isEmpty(null));
System.out.println(StringUtils.isBlank(null));
System.out.println(StringUtils.isNumeric(null));
System.out.println(StringUtils.isAllUpperCase(null));
Output:
true
true
false
false
But before reaching any conclusion don't forget to read the documentation of Null safe methods and classes. This is another Java best practice, which doesn't require much effort, but result in great improvements. You can also see these advanced core Java courses to learn more about writing better Java code and best practices.
4. Avoid returning null from a method, instead, return an empty collection or an empty array.
This Java best practice or tips is also mentioned by Joshua Bloch in his book Effective Java which is
another good source of better programming in Java. By returning an empty
collection or empty array you make sure that basic calls like size(),
length() don'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.
Here is a code example
Here is a code example
public List getOrders(Customer
customer){
List result = Collections.EMPTY_LIST;
return result;
}
Similarly, you can use Collections.EMPTY_SET and Collections.EMPTY_MAP
instead of returning null.
5. Use of annotation @NotNull and @Nullable
While writing method you can define contracts about nullability, by
declaring 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. IntelliJ IDE and findbugs already supports
such annotation.
These annotations are also part of JSR 305, but even in the absence of any tool or IDE support, this annotation itself work as documentation. By looking @NotNull and @Nullable, programmer can himself decide whether to check for null or not.
By the way ,this is relatively new best practice for Java programmers and it will take some time to get adopted.
These annotations are also part of JSR 305, but even in the absence of any tool or IDE support, this annotation itself work as documentation. By looking @NotNull and @Nullable, programmer can himself decide whether to check for null or not.
By the way ,this is relatively new best practice for Java programmers and it will take some time to get adopted.
6. Avoid unnecessary autoboxing and unboxing in your code
Despite of other disadvantages like creating temporary object, autoboxing
are also prone to NullPointerException, if the wrapper class
object is null. For example, following
code will fail with NullPointerException if person doesn't have
phone number and instead return null.
Person ram = new Person("ram");
int phone = ram.getPhone();
Not just equality but < , > can also throw NullPointerException if used
along autoboxing and unboxing. See this article to learn more pitfalls of autoboxing and unboxing in
Java.
7. Follow Contract and define reasonable default value
One of the best way to avoid
NullPointerException in Java is as simple as defining contracts and
following them. Most of the NullPointerException occurs
because Object is created with incomplete information or all required dependency
is not provided. If you don't allow to create incomplete object and gracefully
deny any such request you can prevent lots of NullPointerException down the
road.
Similarly if Object is allowed to be created, than you should work with reasonable default value. for example an Employee object can not be created without id and name, but can have an optional phone number.
Now if Employee doesn't have phone number than instead of returning null, return default value like zero, but that choice has to be carefully taken sometime checking for null is easy rather than calling an invalid number.
On the same note, by defining what can be null and what can not be null, caller can make an informed decision. The choice of failing fast or accepting null is also an important design decision you need to take and adhere consistently.
Similarly if Object is allowed to be created, than you should work with reasonable default value. for example an Employee object can not be created without id and name, but can have an optional phone number.
Now if Employee doesn't have phone number than instead of returning null, return default value like zero, but that choice has to be carefully taken sometime checking for null is easy rather than calling an invalid number.
On the same note, by defining what can be null and what can not be null, caller can make an informed decision. The choice of failing fast or accepting null is also an important design decision you need to take and adhere consistently.
8.Use Non-Null constraints on Database
If you are using database for
storing your domain object such as Customers, Orders etc than
you should define your null-ability constraints on database itself. Since
database can acquire data from multiple sources, having null-ability check in DB
will ensure data integrity. Maintaining null constraints on database will also help
in reducing null check in Java code. While loading objects from database you will be sure, which field can be null and
which field is not null, this will minimize unnecessary !=
null check in code.
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.
The 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.
The 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.
That’s all guys, these are a couple of easy-to-follow Java tips and best
practices to avoid NullPointerException. You would appreciate, how useful these
tips can be, without too much effort. If you are using any other tip to
avoid this exception, which is not included in this list, then please share
with us via comment, and I will include them here.
28 comments :
In point 3 you can add com.google.common.base.Preconditions.checkNotNull, a static method that returns the type provided as argument, so that you can use the function as it were the original object
One of the tip, which I have learned hard way is : avoid chaining of methods, like following code
String city = getPerson(id).getAddress().getCity();
Now this method will throw NullPointerException if person is null, or address is null.Instead of chaining multiple methods, you can create a separate method say getCityFromPerson(int id), that will help you during debugging to find out which field is null.
How can you miss simplest of simple, prefer primitive over Object. Instead of returning Integer, Boolean or Double return primitives like int, boolean and double. Since primitive can not be null, you are sure there would not be any NullPointerException.
com.google.common.base.Optional is one more elegant way to deal with nulls
Thanks @Anonymous and @suraj, I see use of Optional from Guava another good way to deal with null. Thanks for pointing that.
The best practice I think is to consider null references as actual errors. Using null references for program flow should be avoided, and null checks should almost only be necessary for inputs from outside the system.
Jarvin, how is the example at "6) Avoid unnecessary autoboxing and unboxing in your code" related to autoboxing? I think that it's really misleading regarding what autoboxing is...
Hi treaz, It's Javin not Jarvin :), Anyway would you please elaborate, why you think it's misleading? Autoboxing can throw NullPointerException and that's why returning primitive is preferred over wrapper class object e.g. Integer or Boolean, so a code like this
int id = getId();
where getId() returns Integer will fail with NullPointerException, if getId() return a null object.
About point 2: String.valueOf(null) - also returns a null pointer excepiton. How is better than null.toString()? There are other advantages to valueOf() mentioned in Effective Java Chapter 1 but not what you mentioned.
Hello Srujan Kumar it appears that in that special case it throws and exception , but when it receives a null object it does not:
look:
Object c=null;
String.valueOf(c); /// is OK
String.valueOf(null); // trows Exception
I think that String.valueOf(null); is not a common sentence to use ;D
@Jesus Rafael Lopez Ibarra, that's something very good detail about valueOf() method, didn't know that it handle null literal that way.
Thanks a lot for these tips. I've been trying to get some useful tips on null pointer exceptions for some time now.
It's a very useful info towards to valueof() method of String class
#4 should use generics and the solution would be slightly different:
public List getOrders(Customer customer){
List result = Collections.emptyList();
return result;
}
The emptyList() method is generics aware, while EMPTY_LIST is just constant (If I remember correctly, it is a zero length list of Objects).
Hey Javin,
thank you for the tips. Occasionally, I still use null as return value for single object being able to indicate that there something missing ... and if I have to deal with an NPE then I obviously didn't consider every possible situation :) In addition, I usually start my Eclipse instance in debug mode with an debug point on Exception class (don't forget to check "Subclasses of this exception"). I also add an Filter to the package name of my company. So each time there is an unexpected exception, Eclipse will stop an I have enough time to investigate.
@Anonymous
I like method chaining then it makes my actual intention more obvious (temporary variables would add more details that the user needs to skip). While debugging this chain, you could used the following Eclipse features:
- "Inspect" (Shift+Ctrl+I)
- "Step into Selection" (Ctrl+Alt+left mouse) to jump right into the selected method while debugging
Best regards,
Kon
Hi guys,
The best way according to me to handle null check is to write one utility class which has conditions for all the objects like map, String, int and object itself. So that utility will have one method which accept the object and check for the null, if the passed object is null then it will return a false otherwise true. You have to make sure that before using any object in your code, you should have null check by using the method of utility class. For e.g if(utility.exists(object)){}. Might be helpful.
null!=Object,;
Object!=null ;
which one throws null pointer exception
Java 8 has added a class called Optional which will make null handling and avoiding null pointer exception more easy. If you are not using Java 8, then can still uses Google Guava's Optional class, which is even better than Java 8, as it can be used inside foreach loop because it implements Iterable as well. Optional provide clean API and force user to think about what to do when something is null.
I beg to differ that Guava Optional is better than Java 8 Optional. In fact, Guava's Optional does NOT implement Iterable (just check the API docs). On the contrary, Java 8's Optional is in fact a Monad, which is why it is far superior to Guava's.
Given Java 8's Optional#ofNullable(T) there is yet another way to get rid of NPEs:
1. Eliminate the null symbol from your codebase completely. Nothing justifies writing null anywhere these days.
2. Wrap all results to external APIs (libraries, etc.) into Optional via ofNullable (possibly with deep nesting).
Unfortunately, Java sucks, so 2 would have to be applied to all Java JDK API methods as well. I have no idea how someone could introduce Optional, yet still allow Map#get to return null. The price for downward compatibility has become outrageous already. It basically cripples the language.
PS @Javin: Please improve your command of the English language. Even as a non-native speaker, reading your strange grammatical constructions hurts.
Collections.EMPTY_LIST and Collections.emptyList(). Both the methods are immutable. Can you give an example where it can be used?
Below coding guidelines may help to avoid NPE which in turn leads to silent failures as these cannot be traced out through compiler.
1. use "null == object" instead of "object == null" as if we miss out '=' in latter one then leads to NPE if we reference "object" but in the former one it will be a compiler error.
2. use "null != object" instead of "object != null" as if we miss out '!' in latter one then leads to NPE if we reference "object" but in the former one it will be a compiler error.
@GOPI interesting, Surely I can't deny that such mistakes did happen in real world. Thanks for those tips.
Sometimes wrapper classes are needed. For example all collections like hashmap, arraylist, linkedlist are not supporting primitive types.
I use Tip 5 for several years now. It is all I need. Once you use @Nullable and @NotNull annotations you see that none of the rest is needed. Not even joda code. Nullable annotations beats the lot.
Good article ..but does share tha solution for the null pointers exception u describe in ur last article when accessing method of a class from null object
in Java 1.8 wraper class java.util.Optional was added.
it helps with Null handling including for situations were chaining of methods looks much more convenient.
In example below city will wrap a null regardless who was null: person, address or city.
Ex: Optional city = getPerson(id).getAddress().getCity();
In any case you wil have to do somthing about city if it is null, isn't it ?
@Alex, Optional doesn't eliminate nulls but it does provide visibility and expose nulls before NullPointerException. You can use better defaults values with Optionals e.g. if put empty string if city is null.
where the for each will handle null pointer exception, In case if we are trying, list ob=null; for(obj o: ob){} it will trow error or not
Post a Comment