A Consistent Way of Doing Null Checks and Empty Checks on Objects
I have always found null checks and checks for "empty" values (mostly applicable for collections or maps) spread all throughout the code base. Hence I found a neat and elegant way to handle this by providing a utility class that contains the following null checks:
Utils Class:
/**
* This method returns true if the collection is null or is empty.
* @param collection
* @return true | false
*/
public static boolean isEmpty( Collection<?> collection ){
if( collection == null || collection.isEmpty() ){
return true;
}
return false;
}
/**
* This method returns true of the map is null or is empty.
* @param map
* @return true | false
*/
public static boolean isEmpty( Map<?, ?> map ){
if( map == null || map.isEmpty() ){
return true;
}
return false;
}
/**
* This method returns true if the objet is null.
* @param object
* @return true | false
*/
public static boolean isEmpty( Object object ){
if( object == null ){
return true;
}
return false;
}
/**
* This method returns true if the input array is null or its length is zero.
* @param array
* @return true | false
*/
public static boolean isEmpty( Object[] array ){
if( array == null || array.length == 0 ){
return true;
}
return false;
}
/**
* This method returns true if the input string is null or its length is zero.
* @param string
* @return true | false
*/
public static boolean isEmpty( String string ){
if( string == null || string.trim().length() == 0 ){
return true;
}
return false;
}By having these methods as static utility methods, the client code looks neat and you now have a consistent way of doing null checks.
E.g. Client code that needs to do a null check would call Utils.isEmpty(object) or call any other specific overloaded method.
Advantages:
- Consistency in the null check code.
- Avoids littering of code with individual checks for null and emptiness by doing them both in one go. (99% of the cases you want to do both null checks and check for emptiness but rarely one in isolation).
- Easy to read and comprehend.
Disadvantage:
This one is not really a disadvantage but rather something that applies to overloaded method invocation in Java.
If you have code as below, it will not compile.
Utils.isEmpty(null); //This line doesn't compile. It's like testing if(null==null). Just crazy!
I feel it's worth taking this approach since you might never have to write code as above in real life :)
I hope this helps and makes your code more cleaner and reveals intentions more clearly. I would like to hear from the readers of this site on what they think of the above approach.
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)





Comments
Alex Collins replied on Fri, 2010/09/24 - 1:45am
Josh Marotti replied on Fri, 2010/09/24 - 9:21am
What Alex said: common-lang
Quit reinventing the wheel. Even your disadvantages are covered in apache commons.
Bob Morlaix replied on Fri, 2010/09/24 - 10:29am
BTW, code that looks like:
if (<my test>) {can be simplified to:
Clure Rogre replied on Fri, 2010/09/24 - 10:32am
"Utils.isEmpty(null); //This line doesn't compile. It's like testing if(null==null). Just crazy!"
No - it's perfectly logical. To test each of your overloaded methods, use;
Utils.isEmpty((Object)null);
Utils.isEmpty((Object[])null);
Utils.isEmpty((String)null);
... etc
Johannes Brodwall replied on Fri, 2010/09/24 - 10:45am
I like this approach. Much better than dragging in apache commons-lang with all the jetsam and flotsam that is attached to it. It's a good thing to stop reusing square wheels.
However, you probably want to simplify the expressions a bit:
/** Is the argument null or empty? */ public static boolean isEmpty(Collection<?> collection) { return collection == null || collection.isEmpty(); }Simpler and more concise. And no braindead JavaDoc. "@returns false | true" is pretty dumb for a boolean. "@param string" isn't too helpful either. :-)
Simon Peter replied on Fri, 2010/09/24 - 10:53am
Further: rethink the need for those null checks.
I recently started working on an application which has a lot of those checks. Mosts of those checks were not needed.
So with better understanding of the code, you can reduce those checks.
* The String.equals() method is null-safe. You can do
if( "const".equals(const) ){}rather than:
if( const != null && const.equals("const") ){}Greg Allen replied on Fri, 2010/09/24 - 10:59am
Don't permit the usage of null to represent an empty collection. Then you can just call the Collection's empty() method and be done.
Consider using annotations and findbugs to document and enforce non-nullness. See also JSR-305.
Suresh Murthy replied on Fri, 2010/09/24 - 11:11am
Wujek Srujek replied on Fri, 2010/09/24 - 12:21pm
in response to:
Suresh Murthy
"One common pattern I find in the code I have seen is where people don't do null checks and start iterating over collections using enhanced for loop. This obviously leads to NPs and I have had several such instances when I had to fix this by adding an explicit null check. Hence being diligent in using null checks helps"
Making the code null-safe is easy and no-brainer, so fixing such a bug is really seconds. The real question is - why is the collection null in the first place? *This* is the real bug. By doing this null check and ignoring the loop when the collection is null you pretty much disguised a bug as a feature - the application cannot now react correctly to invalid input, and it is very easi to just forget to check the culprit.
I use the approach that when I state in the contract (JavaDoc) that something must not be null or NPE can folow, the caller of my API is buggy if it is null. They will learn it anyways - they will get the nasty NPE - and will have to correct themselves.
Jilles Van Gurp replied on Fri, 2010/09/24 - 1:44pm
First, you are reinventing the wheel. There are several libraries out there that provide similar (and more) functionality. Don't reinvent wheels, it just complicates maintenance.
Second, having to do lots of validation checks is a design smell. It indicates you are uncertain about how you are going to be called. You shouldn't have to care. If that code is a public facing API, then yes, you probably should do some validation (there are several frameworks for that too) and fail gracefully. If it is internal, that is a design smell. Fail fast. A null pointer exception is ugly but it will point the finger right at the offending bit of code and fixing it is easy. Pre-emptively littering your code with redundant null checks will result in a lot of dead code that never gets executed and a lot of edge cases that are hard to test.
Third, just like you should be handling exceptions way up the stack, you should be pushing validation up the call stack as well: do it once and do it well. That way most of your code is free of either exception handling or validation except where it faces the outside world. Separate those concerns from your business logic.
Finally, it's much better to be very conservative about what you return (i.e. don't return null if you can avoid it) than it is too litter your code with null checks. Null is the lazy option. And if you are going to return null, indeed document it and provide a unit test. If you have complex model objects, use constructors, factories, builders, or mapping tools (e.g. dozer) that do all the right things and don't go off and manually instantiate empty objects and manually populate them with setters. If you don't introduce null values into the system, you will see a lot less npe's. And if you accidentally do run into nulls, you will know because it breaks and fails fast. You want it to break fast so that you can fix the problem, which is that you introduced a null value into the system somewhere and not that you failed to check for it.
Amin Mansuri replied on Fri, 2010/09/24 - 5:36pm
in response to:
Jilles Van Gurp
I beg to differ. Checking parameters for validity indicates that you are using defensive programming a tried and true method of writing code that is resilient to changes.
In an ideal world people will obey your API and never send an unwanted null or empty string, but in the real world such things happen. Then what saves you is to "fail early, fail hard!". The sooner you can detect the problem the better.
When code changes all around you (as it does in very large projects), defensive programming can detect mistakes quickly and your code comes out clean.
Also, optionally you can turn off the validation checks.. though I never bother to.. because in production it is often great to have detected an error and have it logged and know the earliest manifestation of the problem.
Liam Knox replied on Fri, 2010/09/24 - 5:52pm
in response to:
Jilles Van Gurp
I also agree internal you should have stronger contract so you are dealing with null or preferable empty in the cases of collections and not both
However, I do still have some concerns in very small projects where you pull in a whole depedency tree's for a very small subset of behaviour, i.e. a class or even a specific method. I would say there are edge cases where the duplication approach makes sense in limiting growth and inter-dependencies, especially if you then find out this one method you need is atomic but the library it is in actually depends on several others
Again I think there is often no pure perfect solution, though I do feel dependency resolution could become better evolved.
For certain API's in Apache commons or indeed Google collections you would hope they could even be considered for the main Java API in some later release in some form by API or possible language extension
mike toth replied on Fri, 2010/09/24 - 7:04pm
I don't think it's really fair to assume that in most cases, it's better to import a third party library than to write extremely simple utility functions.
For something relatively involved, the case for importing a library is much stronger, but for basic "verbosity reduction" functions such as this, unless you are -already- using apache-commons it's frankly silly to pull it in. A few lines of code alone are not worth the effort of adding to the dependency matrix and going to third party source to read the code.
For virtually any contribution of code technique to this forum, one can find some third party library that covers that functionality plus a lot more. It seems that this often results in the tired "don't re-invent the wheel" admonishment.
I think that folks are missing the point that regardless of who's "wheel" you use, and whether that particular "wheel" is appropriate for a given project, understanding how a given type of "wheel" works and where it may be useful is orthogonal to whether it is provided by a third party or not.
I would hope that those who use third party libraries to perform various functions would still want to understand the details, to an extent, of how those functions are implemented within that library.
Tomi Tuomainen replied on Sat, 2010/09/25 - 5:03am
I hate this "stop reinventing wheel" whining. Why not to write your own implementation, if it takes just a couple of minutes? Avoid hassling with another dependency and you have all the code in your hands. It's easy to modify if you need to change the default behaviour.
But of course, if commons-lang is part of our default kit, we will use that. And this post is quite irrelevant anyway. If you have any serious coding experience, you already know that you should avoid copy-paste code (with or without commons-lang).
Matt Corgan replied on Sat, 2010/09/25 - 1:47pm
I wish the java.util.Collections class had a few of these, but I guess they decided it's too hard to draw the line on where to stop.
I've never been able to wrap my head around the "collections should never be null" argument. Using one library that returns null even once throws a wrench in that plan, unless you want to patch it. I'm pretty sure i've encountered that over the years in spring, hibernate, lucene, and others, not to mention less well-known libraries. Once you start handling the nulls this way it becomes second nature.
Liam Knox replied on Sun, 2010/09/26 - 5:45am
in response to:
mike toth
Knowing the good API's is a fundamental skill these days. Also knowing an API that is familiar to others and has been tested by thousands in the field is generally better than reinventing a wheel that you may make accidentally square.
Christian Schli... replied on Sun, 2010/09/26 - 5:51am
Suresh Murthy replied on Mon, 2010/09/27 - 1:54am
@Mike Toth,
The above code was written and used primarily because we did have a restriction in the project not to use any open source libraries.
I totally agree with your point that we all are curious to know how something works or how something has been coded.If not for re-using it, just to learn from other's experience. It just doesn't mean that everytime there exists, a third part library, I am gonna stop writing something similar on my own. If I find a need to do it, I shall always do it.
If I have the freedom to use open source, I would by all means use the open source library and get things done quickly.
@Matt Corgan,
I feel it's time java adds these kind of utility stuff in to their main stream APIs like the way you pointed out.
Suresh Murthy replied on Mon, 2010/09/27 - 2:03am
in response to:
Liam Knox
@Liam Kno,
You hit the nail on it's head.
"However, I do still have some concerns in very small projects where you pull in a whole depedency tree's for a very small subset of behaviour, i.e. a class or even a specific method. I would say there are edge cases where the duplication approach makes sense in limiting growth and inter-dependencies, especially if you then find out this one method you need is atomic but the library it is in actually depends on several others".
The point that I need to use a very very small subset of the features offered by a library, there are times, when I am very cautious to know if it's wise to pull in the entire dependency of the third party library. I would try to see if I can just get those subset written by myself. If it's possible, I would do it.
The last sentence in your above comment, it even stronger a reason for me to cautious.