pagetop
Javablog
by Java coders, for Java coders RSS

null Parameters and returning null

May 7th, 2007 by Sam

I am not a fan of methods that accept null and I can find very few reasons for ever wanting to return null. Once a null gets into your code it can cause havoc, which is best discovered as soon as possible during development as it either indicates a serious problem or a buggy method returning null under certain circumstances (usually instead of an empty Collection).

How many times have you had to rewrite a simple equals call to allow for a null? The option usually comes down to explicitly doing a != null, and only then performing the check, or writing the equivalent of

"A String".equals(parameter);

which is just plain backwards!

I was very happy when it finally occurred to me that Java 5’s varargs could be used to create this helpful little method

static public void notNull(Object... objects) {
    for (Object o : objects) {
        if (o == null)
            throw new NullPointerException();
    }
}

When used as the first line of any method, it catches null parameters before they get lost… otherwise it takes some digging with a debugger to find where they came from. I often wonder if the Java designers shouldn’t have forced all parameters to be non-null, allowing null only if the method declaration had a keyword nullable or something similar.

When is a null parameter acceptable

I don’t think I’ve ever seen a method that accepts null with good reason, although many methods allow it. There are situations that can be forgiven, such as signifying to the method that a default value is fine for this parameter. However, it is often possible to avoid accepting null with good API design and method overloading. Even in the case where null signifies a default value, it is not clear from reading client code what is going on… especially if there are several nulls.

Can anything think of any more?

When is it acceptable to return null

I personally believe that a method should not need to return null where a checked Exception makes sense. If an explicit check for the exceptional case is common, then it may be forgiven… for example when a Map does not contain a key it will return null, but Map.containsKey() provides the explicit check to confirm this since null is actually a valid value (a strange choice in API design, I’m sure they had their reasons because HashTable didn’t allow null keys or values.).

But philosophical belief and practice are two very different things… in reality I often return null instead of throwing an Exception when there is only one exceptional state and the exceptional state is akin to false, e.g. there was no cached solution or it failed for a singularly predictable reason. Yeah, I know, it’s total hypocrisy… but non-public code is ugly by definition ;-)

UPDATE: I recently noticed that the Google Collections API (a nice set of useful utilities and classes) has a Nullable annotation :-)


This entry was posted by by Sam on Monday, May 7th, 2007 at 6:05 pm, and is filed under Basic, Java, Methods, Parameters, null, varargs. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.



10 comments on “null Parameters and returning null”

It’s perfectly acceptable for methods to return null if it’s part of the normal processing. Exceptions are very expensive and should only be used for… well, exceptional cases.

For example, not finding a key in a map is perfectly acceptable and part of the Map contract (it’s also quite frequent). Throwing an exception there would be an abuse.

Thanks for that “x”… although you do realise my example for “when is it acceptable to return null” was exactly Map.get()? However, note that in the case of Map.get(), a null return doesn’t mean the key doesn’t exist… it can mean the key doesn’t exist or the value has actually been set to null, you should really be using Map.containsKey(), which really makes a difference if value-lookup is expensive (e.g. in a database).

I’d like to hear you elaborate on what you mean by “normal processing”… some people hate dealing with checked Exceptions and other people (like me) hate dealing with null references. The problem with the former is that there is the temptation to ignore a checked Exception, whereas with the latter the problem is in forgetting to deal with it and revisiting the code doesn’t alert you to this.

If the null return value is actually a signal to an exceptional case (as you rightly point out), then I don’t see why an Exception shouldn’t be used, as it avoids unwelcome nulls hanging around.

As a side note, the performance overhead in throwing an Exception is so low these days that I wouldn’t even consider it an issue unless it was a mission critical class that was being used extensively in computational code. Life is too short to worry about optimisation at this level, unless you have a performance problem and profiling has pinned it down.

raveman wrote:

I agree that throwing exception doesnt cost that much, I remind me of all the xml hate and how xml parsing is so slow that we should never use it :> and ajax should be ajaH(TML), but ajax and SAO are doing good.

In Map you have full control of what youre doing, i never use Map.containsKey() - i never needed it. If Map.get() returns null that means that it doesnt have the object that i wanted, i never want null from Map.

maybe i return null because all the try-catch’s make code look less readable(i hate checked exception because most of the time there should be unchecked exception - for example IOException should be unchecked(I always re-throw it or try to pass it to the method), FileNotFoundException also should be unchecked - if program fails when file is not found i dont care about catching this exception(i also never use it, because there is File.exist() method). However if your company is using metrics you should use checked exception more - because they produce more code(more code = less readable).

i hate metrics because they produce bad code, why should anybody write clean code when the more you write the better you are?

Raveman, totally hear what you’re saying about null values in Maps… but recently we’ve been using database-backed Map implementations and the look-up is much more costly than the Map.containsKey() call. I would still never insert a null as a value though, and have a hard time imagining a good use case. The only example I can think of would be as a cache, which would be best done with Future and WeakReference. It must have been important though, because they explicitly allowed null when upgrading the old HashTable and Vector system to Collections.

If you don’t like checked Exceptions, then check out ExceptionAdapter on Bruce Eckel’s article. It allows you to wrap any checked Exception into an unchecked Exception

That said, I would have to disagree about unchecked Exceptions for IO issues though. I believe unchecked Exceptions should only be thrown when it is impossible to recover, or when a class is implementing an Interface that doesn’t permit the kinds of Exceptions you have, and you can’t recover from it… indicating a major bug. In many cases it is possible to recover from an IOException… prompt the user for another file, or go to the next file in a list and log it.

We don’t code by metrics, but I find checked Exceptions (when checked! not simply dropped) produce much more stable code. We had a situation recently where we had changed a checked Exception into an unchecked one, and coded for a while. A week later, three unit tests started to fail. It wasn’t until we went digging that we realised we forgot that the method threw the unchecked Exception, and we’d forgotten to catch it… all in the name of code cleanliness. It’s these kinds of issues that prompted us to create this week’s poll! :-)

raveman wrote:

You can also recover from OutOfMemoryError :P When i think about checked exception i always think about SQLException or IOException. Your example is one of the cases when you can catch it, but what if you create files and you know they should be there and they arent for some reason-maybe bug or you cannot write to directory. SQLException is even better example ;)

I just think that when you almost always need to catch exception and do something than it should be checked, but if not than it should be unchecked.

How do you feel about IllegalArgumentException ? I think that exception teach you that you should remember about unchecked ;) you can always write in declaration “throws IllegalArgumentException”.

P.S. Thanks for Bruce Eckel’s article, but its too complicated for me, i just do

try { try { throw new FileNotFoundException(); } catch (FileNotFoundException e) { throw new RuntimeException(e); } } catch (Throwable e) { if (e.getClass().equals(RuntimeException.class)) { e.getCause().printStackTrace(); } }

its simpler :)

raveman… if you copy Bruce’s code into your codebase, then it means that you can catch runtime exceptions and then wrap them in throw new ExceptionAdapter(e);. It does essentially what you’re doing but in a lot less code and more generic :-).

Totally agree - by avoiding returning null you avoid potential NPEs in your caller’s code.

But where null does become an option is, as a previous commentator mentioned, when there’s a database involved and the null could mean SQL null (as in no information in the DB)

But apart from that I agree - one should check for null parameters in public methods and never return null from a method call

-Frank

See my website for my treatment of null return values. Throwing exceptions is pushing the problem from some (non-locatable) NPE to some other (located) exception. But if null is not an error if find the use of an exception inappropriate. Much cleaner is the NullObject pattern that allows he caller not to care about possible “missing data” sitaution and thus makes the method much easier to use.

Thanks Carsten…your excellent references

are absolutely spot on, although I would seriously contend the position that all null values are errors… for example, people commonly use null as a shorthand for “not found” (in the case of a Map-backed class, or “no more calls required” in recursive methods, which most certainly aren’t errors.

btw, Tor Norbye’s coding advice is a fantastic find.

[…] guter Artikel über null als akzeptierter Methodenparamter und den Rückgabewert null in Java: I am not a fan of […]

Leave a comment

Markdown is supported.

To include code snippets in your comment, use

<pre><code># lang java
... code here ...
</code></pre>

or use 4 spaces at the start of the line instead of using code and pre tags.

Comment feed: RSS