Avoid Null Pointer Exception in Java
First let’s create example that raise Null Pointer Exception
private Boolean isFinished(String status) { if (status.equalsIgnoreCase("Finish")) { return Boolean.TRUE; } else { return Boolean.FALSE; } }
In previous method if we pass the value of “status” variable as null it will raise Null Pointer Exception in below line
if (status.equalsIgnoreCase("Finish")) {
So we should change my code to below code to avoid Null Pointer Exception
private Boolean isFinished(String status) { if ("Finish".equalsIgnoreCase(status)) { return Boolean.TRUE; } else { return Boolean.FALSE; } }
In previous method if we path the value of “status” variable as null it will not raise Null Pointer Exception.
If you have object.equals(”literal”) you should replace with “literal”.equals(object) .
If you have object.equals(Enum.enumElement) you should replace with
Enum.enumElement.equals(object).
At general expose equals method of the object that you are sure that it doesn’t has null value.
I will continue in providing more best practice and advices.
In part 1 post I listed how to avoid NPE in equalsIgnoreCase() method and enumerator, today I will write about below cases
1- Empty Collection
2- Use some Methods
3- assert Keyword
4- Assert Class
5- Exception Handling
6- Too many dot syntax
7- StringUtils Class
Empty collection is collection which hasn’t any elements. Some developers return null value for Collection which has no elements but this is false, you should return Collections.EMPTY_LIST, Collections.EMPTY_SET and Collections.EMPTY_MAP.
Wrong Code
public static List getEmployees() { List list = null; return list; }
Correct Code
public static List getEmployees() { List list = Collections.EMPTY_LIST; return list; }
2- Use some Method
Use some methods to assure that null value not exist like contains(), indexOf(), isEmpty(), containsKey(), containsValue() and hasNext().
Example
String myName = "Mahmoud A. El-Sayed"; List list = Collections.EMPTY_LIST; boolean exist = list.contains(myName); int index = list.indexOf(myName); boolean isEmpty =list.isEmpty(); Map map =Collections.EMPTY_MAP; exist=map.containsKey(myName); exist=map.containsValue(myName); isEmpty=map.isEmpty(); Set set=Collections.EMPTY_SET; exist=set.contains(myName); isEmpty=set.isEmpty(); Iterator iterator; exist = iterator.hasNext();
3- assert Keyword
assert is keyword provided in Java 1.4 which enables you to test your assumptions about your code.
Syntax of assert keyword
assert expression1 ;
expression1 is boolean expression which is evaluated and if it is false system will throw AssertionError with no detail message
assert expression1 : expression2 ;
expression1 is boolean expression which is evaluated and if it is false system will throw AssertionError and detail message is expression2
For example in my post I want to assert that expression is not null then I should write below code
public static String getManager(String employeeId) { assert (employeeId != null) : "employeeId must be not null"; return "Mahmoud A. El-Sayed"; }
If I try to call getManager method using getManager(null);
It will raise “java.lang.AssertionError: employeeId must be not null”
Note use -enableassertion in your java option while run your code to enable assertion.
4- Assert Class
Assert class exists in com.bea.core.repackaged.springframework.util package and has a lot of methods used in assertion.
Example
public static String getManager(String employeeId) { Assert.notNull(employeeId, "employeeId must be not null"); Assert.hasLength(employeeId, "employeeId must has length greater than 0"); return "Mahmoud A. El-Sayed"; }
If I try to call getManager method using getManager(null);
It will raise “java.lang.IllegalArgumentException: employeeId must be not null”
5- Exception Handling
I should take care in exception handling using try catch statement or checking of null value of variables
For example
public static String getManager(String employeeId) { return null; }
I will cal it using below code
String managerId = getManager("A015"); System.out.println(managerId.toString());
It will raise “java.lang.NullPointerException” , so to handle this exception I should use try catch or checking of null values
a- try catch statement
I will change calling code to below code
String managerId = getManager("A015"); try { System.out.println(managerId.toString()); } catch (NullPointerException npe) { //write your code here }
b- Checking of Null values
I will change calling code to below code
String managerId = getManager("A015"); if (managerId != null) { System.out.println(managerId.toString()); } else { //write your code here }
6- Too many dot syntax
Some developers use this approach as he writes less code but in the future will not be easier for maintenance and handling exception
Wrong Code
String attrValue = (String)findViewObject("VO_NAME").getCurrentRow().getAttribute("Attribute_NAME");
Correct Code
ViewObject vo = findViewObject("VO_NAME"); Row row = vo.getCurrentRow(); String attrValue = (String)row.getAttribute("Attribute_NAME");
7- StringUtils Class
StringUtils class is part of org.apache.commons.lang package, I can use it to avoid NPE specially all its methods are null safe
For example StringUtils. IsEmpty(), StringUtils. IsBlank(), StringUtils.equals(), and much more.
You can read specification of this class from here
Conclusion Always take care of NullPointerException when writing code and guess how it will be thrown in your code and write //TODO in your code for solving it later if you haven’t more time.
Reference: Avoid Null Pointer Exception Part 1, Avoid Null Pointer Exception Part 2 from our JCG partner Mahmoud A. ElSayed at the Dive in Oracle blog.
Defensive programming is a powerful tool that you should use with care. Sure thing you must be defensive. But be very careful that you do not alter behavior of a function or class just because an object is null. If you get a null object that is not allowed, a null-pointer is quite a good indication of what’s wrong and definitely better than IllegalArgumentException. In non-public APIs, adding null-checks and adding special behavior for null-objects (like throwing other exceptions, or logging and continuing in another branch) is a smell that you don’t trust you team for properly testing their code.… Read more »
The Guava Optional class is an excellant way to avoid NPE’s as well.
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Optional.html
https://plus.google.com/u/1/117071755921589242651/posts/86Fadmqdbpf
Returning null puts workload on the users of your API so it should be avoided. The too-many-dots approach should be avoid because you are having too much knowledge of the object graph in one method and this is against OOP principles, making changes difficult to made, as you said. But your correct code is the same but with variables, a much better way is to move that code to its own method in the View object and use that instead of navigate the object graph every time. The try-catch approach is like killing a mosquito with a bazooka.
1. You are talking about avoiding NullPointerException while you return Boolean (nullable object) where simple boolean (primitive) is sufficient.
2. Collections.emptyList() is preferred due to better handling of generics.
3. com.bea.core.repackaged.springframework.util – what? Why not use assertions in Guava or Apache Commons Lang?
4. I have never seen legitimate use case for catching NullPointerException, please do not encourage to do so.
good site
???
Good article. Thank you for the information
At number 5, Handling Exception, You said that catching null pointer exception is an alternative for null check.
However Catching NullPointerException is not a good practice. Doing null chek is better than this alternative.
Very informative article. Thank You