Just Say No to Nulls (or Refactoring Your Way to Programmer Bliss)
I can’t help but feel my code is getting harder and harder to read as I wade through an ever increasing number of if != null checks before finding my way to the real logic that I actually care about…
But, man, now there’s even more code and all I’m doing are a few simple checks.
Doesn’t it feel like there has to be a better way?!
Well, actually yes, there is.
Stop allowing any of your methods to return nulls.
No nulls returned, no null checks necessary. Thank you for reading.
Oh, you’re still here. Yeah, that’s a little easier said then done, isn’t it? Particularly if you’re working on existing applications with thousands of lines of null returning code. And let’s not even get started on 3rd party libraries.
The problem, of course, is that if we only manage to remove some of the null returns, developers are going to have to remember which methods can return null and which ones can’t. And the first time they’re hit with our favorite NullPointerException they’re going to go “shit!” and start adding those if != null checks all over the code again.
And so, it starts to feel like an all or nothing scenario to get out of null check hell. Either we prevent ALL of our methods from returning null and ascend into programming bliss. Or, we’re stuck with those damn null checks.
Well, the good news is that when it comes to code, improving even one small element tends to exert a positive influence on our overall design. And so, even by tackling some of our null returns, we actually end up with better, easier to maintain software. And, if we’re able to do it in a structured way — say, a policy of fixing NPEs by changing the method to not return null rather than inserting an if != null check, or taking our most heavily used component and just removing all null returns from it — then I think we can alleviate some of our brain pain.
So, okay, where do we start?
The worst culprits are the getter methods that return objects. When we have classes that return instances of other classes, which in turn return instances of yet other classes, pretty soon we wind up with a lot of method chaining
myObject.getFoo().getBar().getName().rhymesWith( “Banana” )…
and this is the worst thing we can do because there isn’t even anywhere to squeeze a null check into there.
The truth is, when we find ourselves wading through endless object hierarchies such as these, that there is what we call a code smell. And it’s a pretty good indication that we might want to revisit our design. A true OO design is composed of nice little well behaved classes that expose methods we can call on to have them do things for us. These classes abstract the nitty gritty behind the scenes details and just do it (often without the need to return any value at all).
dog.bark() not dog.getAnatomy().getVoiceBox().EmitSound( “woof” )
This is a great opportunity to see if we can’t remove some unnecessary code and complexity with a bit of encapsulation. Is it possible that the parent object can just take care of what we need without showing off how the sausage is made? If so, believe me – not only will we thank ourselves the next time we need that functionality, but so will the other developers. And, look ma, no null returns!
If not (or maybe we’re just not prepared to go quite that far at the moment), we can still ask ourselves if we really need all those getter & setter methods in the first place. Ctrl-Shift-G is one of my favorit’ist ever hot keys in Eclipse (and Resharper’s equivalent in Visual Studio). Sure, we know it’s bad design to make our instance variables public. But, are we really gaining that much when we make our variables private but then turn around and blindly provide public get/set methods for each and every one of them?
If we can lighten our code by even a few methods, not only are we removing some of those pesky null returns, we’re also reducing our maintenance costs by removing unneeded code. And that’s a Good Thing.
Of course, even after all of this cleaning, we’ll still have some methods that just want to return null. But, even so, a lot we can handle by simply returning an empty instance of the object or collection where we previously would have returned null. Sure, it still requires an if != null check in the get method, but we’ve at least moved that check to a single location rather than letting it perpetuate throughout the code. And this too is a Good Thing, so we’re making our code better as we go – even if it’s 1 tiny method at a time.
What is your project’s policy on returning nulls? When you get a NullPointerException, do you fix it by adding an if != null chec
k? Or by altering the method to stop returnin