I've heard some voices saying that checking for a returned null value from methods is bad design. I would like to hear some reasons for this.
pseudocode:
variable x = object.method()
if (x is null) do something
I've heard some voices saying that checking for a returned null value from methods is bad design. I would like to hear some reasons for this.
pseudocode:
variable x = object.method()
if (x is null) do something
Who says this is bad design?
Checking for nulls is a common practice, even encouraged, otherwise you run the risk of NullReferenceExceptions everywhere. Its better to handle the error gracefully than throw exceptions when you don't need to.
G'day,
Returning NULL when you are unable to create a new object is standard practise for many APIs.
Why the hell it's bad design I have no idea.
Edit: This is true of languages where you don't have exceptions such as C where it has been the convention for many years.
HTH
'Avahappy,
Based on what you've said so far, I think there's not enough information.
Returning null from a CreateWidget()method seems bad.
Returning null from a FindFooInBar() method seems fine.
For certain scenarios, you want to notice a failure as soon as it happens.
Checking against NULL and not asserting (for programmer errors) or throwing (for user or caller errors) in the failure case can mean that later crashes are harder to track down, because the original odd case wasn't found.
Moreover, ignoring errors can lead to security exploits. Perhaps the null-ness came from the fact that a buffer was overwritten or the like. Now, you are not crashing, which means the exploiter has a chance to execute in your code.
It depends on the language you're using. If you're in a language like C# where the idiomatic way of indicating the lack of a value is to return null, then returning null is a good design if you don't have a value. Alternatively, in languages such as Haskell which idiomatically use the Maybe monad for this case, then returning null would be a bad design (if it were even possible).
The rationale behind not returning null is that you do not have to check for it and hence your code does not need to follow a different path based on the return value. You might want to check out the Null Object Pattern which provides more information on this.
For example, if I were to define a method in Java that returned a Collection I would typically prefer to return an empty collection (i.e. Collections.emptyList()
) rather than null as it means my client code is cleaner; e.g.
Collection<? extends Item> c = getItems(); // Will never return null.
for (Item item : c) { // Will not enter the loop if c is empty.
// Process item.
}
... which is cleaner than:
Collection<? extends Item> c = getItems(); // Could potentially return null.
// Two possible code paths now so harder to test.
if (c != null) {
for (Item item : c) {
// Process item.
}
}
It's fine to return null if doing so is meaningful in some way:
public String getEmployeeName(int id){ ..}
In a case like this it's meaningful to return null if the id doesn't correspond to an existing entity, as it allows you to distinguish the case where no match was found from a legitimate error.
People may think this is bad because it can be abused as a "special" return value that indicates an error condition, which is not so good, a bit like returning error codes from a function but confusing because the user has to check the return for null, instead of catching the appropriate exceptions, e.g.
public Integer getId(...){
try{ ... ; return id; }
catch(Exception e){ return null;}
}
Other options to this, are:
returning some value that indicates success or not (or type of an error), but if you just need boolean value that will indicate success / fail, returning null for failure, and an object for success wouldn't be less correct, then returning true/false and getting the object through parameter.
Other approach would to to use exception to indicates failures, but here - there are actually many more voices, that say this is a BAD practice (as using exceptions may be convenient but has many disadvantages).
So I personally don't see anything bad in returning null as indication that something went wrong, and checking it later (to actually know if you have succeeded or not). Also, blindly thinking that your method will not return NULL, and then base your code on it, may lead to other, sometimes hard to find, errors (although in most cases it will just crash your system :), as you will reference to 0x00000000 sooner or later).
Unintended null functions can arise during the development of a complex programs, and like dead code, such occurrences indicate serious flaws in program structures.
A null function or method is often used as the default behavior of a revectorable function or overrideable method in an object framework.
It's not necessarily a bad design - as with so many design decisions, it depends.
If the result of the method is something that would not have a good result in normal use, returning null is fine:
object x = GetObjectFromCache(); // return null if it's not in the cache
If there really should always be a non-null result, then it might be better to throw an exception:
try {
Controller c = GetController(); // the controller object is central to
// the application. If we don't get one,
// we're fubar
// it's likely that it's OK to not have the try/catch since you won't
// be able to really handle the problem here
}
catch /* ... */ {
}
What alternatives do you see to returning null?
I see two cases:
In this case we could: Return Null or throw a (checked) exception (or maybe create an item and return it)
In this case we could return Null, return an empty list or throw an Exception.
I believe that return null may be less good than the alternatives becasue it requires the client to remember to check for null, programmers forget and code
x = find();
x.getField(); // bang null pointer exception
In Java, throwing a checked exception, RecordNotFoundException, allows the compiler to remind the client to deal with case.
I find that searches returning empty lists can be quite convenient - just populate the display with all the contents of the list, oh it's empty, the code "just works".
Well, it sure depends of the purpose of the method ... Sometimes, a better choice would be to throw an exception. It all depends from case to case.
Here's the reason.
In Clean Code by Robert Martin he writes that returning null is bad design when you can instead return, say, empty array. Since expected result is an array, why not? It'll enable you to iterate over result without any extra conditions. If it's an integer, maybe 0 will suffice, if it's a hash, empty hash. etc.
The premise is to not force calling code to immediately handle issues. Calling code may not want to concern itself with them. That's also why in many cases exceptions is better than nil.
Exceptions are for exceptional circumstances.
If your function is intended to find an attribute associated with a given object, and that object does has no such attribute, it may be appropriate to return null. If the object does not exist, throwing an exception may be more appropriate. If the function is meant to return a list of attributes, and there are none to return, returning an empty list makes sense - you're returning all zero attributes.
Good uses of returning null:
Bad uses: Trying to replace or hide exceptional situations such as:
In those cases throwing an exception is more adequate since:
However, Exceptions should not be used to handle normal program operation conditions such as:
Sometimes, returning NULL is the right thing to do, but specifically when you're dealing with sequences of different sorts (arrays, lists, strings, what-have-you) it is probably better to return a zero-length sequence, as it leads to shorter and hopefully more understandable code, while not taking much more writing on API implementer's part.
If the code is something like:
command = get_something_to_do()
if command: # if not Null
command.execute()
If you have a dummy object whose execute() method does nothing, and you return that instead of Null in the appropriate cases, you don't have to check for the Null case and can instead just do:
get_something_to_do().execute()
So, here the issue is not between checking for NULL vs. an exception, but is instead between the caller having to handle special non-cases differently (in whatever way) or not.
If you read all the answers it becomes clear the answer to this question depends on the kind of method.
Firstly, when something exceptional happens (IOproblem etc), logically exceptions are thrown. When exactly something is exceptional is probably something for a different topic..
Whenever a method is expected to possibly have no results there are two categories:
Untill we have an official way to denote that a function can or cannot return null, I try to have a naming convention to denote so.
Just like you have the TrySomething() convention for methods that are expected to fail, I often name my methods SafeSomething() when the method returns a neutral result instead of null.
I'm not fully ok with the name yet, but couldn't come up with anything better. So I'm running with that for now.
Make them call another method after the fact to figure out if the previous call was null. ;-) Hey, it was good enough for JDBC