I am currently working with a leading MNC as a Java/J2EE Developer. I am passionate about blogging, reading books and listening to music. You can read my blogs @ https://iduvejeevana.wordpress.com/ Suresh has posted 9 posts at DZone. View Full User Profile

A Consistent Way of Doing Null Checks and Empty Checks on Objects

09.24.2010
| 18168 views |
  • submit to reddit

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:

  1. Consistency in the null check code.
  2. 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).
  3. 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.

1.2
Your rating: None Average: 1.2 (5 votes)
Published at DZone with permission of its author, Suresh Murthy.

(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

You could just use Apache Commons Lang which has a host of such methods :)

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>) {
   return true;
}
return false;

 

can be simplified to:

return <my test>; 

 

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

Like said: use Apache commons-lang

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.
  • The variable was previously used. Any possible null exception would already be thrown. So the check took place too late.
  • The check was on a application critical variable. If that variable were to be null (it never was), the application simply did nothing. So an exception should have been right to indicate a serious problem
  • Looping through an empty list will not perform the loop (if the loop is done correctly).
  • If the used method can handle the null value, why do another check.
  • Null check when using String constants.*
  • Null check when previously a value was assigned.
  • Use empty list in favor of null.


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

@ Alex and Josh, Thanks for the comments. I haven't used the Apache APIs that you have referred above. Will look into them. @ Clure Rogre, Thanks for bringout this up.. Makes sense.. When I tested these methods, I pretty much tested them by actually creating instances that would invoke the specific overloaded method for null check. @Johannes Brodwall, Agree with your point. It can actually simplify the check as you have mentioned. @ Simon Peter, Very good points. I agree with most of them. 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.

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

"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."

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 would have to say I agree with this almost entirely. By taking an API that is likely well known to others, extensively tested by thousands of developers in production, you are in a far better place and that is what you should do

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 keep some similar classes, and even add other null-safe methods like size(Coll...), getFirst(...), getLast(..)

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

Don't under estimate what simple really means. Considering Math.random() is fundamentally flawed why would I trust your implementation of another simple function?

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

As someone already said, you should better simply dereference your collection reference parameter as soon as possible and document a potential NullPointerException in your Javadoc. This would result in robust code which fails fast and always meets its API contract. If in doubt, prefer a NULL pattern (see GoF book).

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. 

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.