don't return null -- what to return for search function

Go To StackoverFlow.com

2

All. I am reading a book called and one of the idea is "Don't return null" when writing a method. He suggests either "throw out exception" or "use special case" when the function has to return null.

If the method return type is a list, I know I can return a empty list instead of null. However, what if the return type is a specific object. For example, a method to search database by unique id and return the result. What should I return if the method can not find anything?

I tried to use "throw out exception" but end up writing more coded and additional logic for any place calls the function.

Any suggestion will be appreciated.

2012-04-05 21:41
by Noodar
possible duplicate of Get around java's try/catch and keep the code clean without returning a nullTomasz Nurkiewicz 2012-04-05 21:56
How's the book called - hithwen 2013-10-14 15:53
it is call “clean code” but I guess stackoverflow doesn't like the name appear on the post so someone remove i - Noodar 2013-10-16 05:37


1

Throwing an exception is an expensive operation, since there is a context switch and a lot of debug information has to be gathered, so you want to avoid throwing them as a way to control process flow (especially if you can handle the situation without throwing exceptions). Returning a null can be perfectly acceptable in order to avoid catching exceptions.

An example of this in action would be a couple of LINQ functions in C#. These methods can return a null:

SingleOrDefault(); // returns a single instance of an object, or null if not found

FirstOrDefault(); // returns the first matching object, or null if not found

This allows you to check for null without trying to figure out control flow using exception handling.

One exception (pardon the pun) that I can think of is using exceptions to communicate across program boundries. If you had, for example, a data access layer in a separate DLL, and you needed to communicate a database failure back to the parent program, sometimes the best way to do that is through exception handling.

2012-04-05 22:26
by mgnoonan


3

If you don't want to return null, then you could use something like an Optional class.

2012-04-05 21:55
by fgb
What is the benefit of Optional. From my perspective, it only change the (obj == null) into (optional.absent() - Noodar 2012-04-06 16:45
It gives some extra type safety to the code - a null is more ambiguous in its intent and can lead to subtle bugs if the client doesn't handle it correctly. The motivation for guava is at: http://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplaine - fgb 2012-04-06 17:11


1

Null is defined as non-existence, which seems to fit in perfectly with what you want. If your code returns nothing return nothing, right?

BUT, as always, it depends.

If your code is not meant to return nothing then doing so can cause untold problems. In this case it's definitely better to throw an exception. 1 / null, won't work everywhere.

If non-existence is a perfectly valid return value then why would you want to return an exception? Assuming of course that you've got the code in place to deal with a non-existent value being returned from your query then there's no need to throw an exception at all.

2012-04-05 21:55
by Ben
agree. In my case, the method might find nothing so null does make sense. but people keep talking about "method should never return null". I find hard to really implement such ide - Noodar 2012-04-06 16:47


1

If Null might be a possible value you could return, then you should not return Null if you cannot find anything. For example, in:

[1, 2, 3, Null, 5].find(nonInteger) -> Null
[1, 2, 3, 4].find(nonInteger) -> Null

the .find function cannot return Null to indicate failure, because sometimes it would return Null on success! Instead, you can either change the semantics, or use a special object:

# changed semantics (with extra information returned)
[1, 2, 3, Null, 5].find(nonInteger) -> index=4, value=Null
[1, 2, 3, 4].find(nonInteger) -> index=Null, value=Null

# changed semantics (with wrapper)
[1, 2, 3, Null, 5].find(nonInteger) -> new Maybe(Null)
[1, 2, 3, 4].find(nonInteger) -> new Maybe()

# special object
NoResultFound = new object()
[1, 2, 3, Null, 5].find(nonInteger) -> Null
[1, 2, 3, 4].find(nonInteger) -> NoResultFound
2012-04-05 22:41
by ninjagecko


0

I don't see any problem with returning null, but throwing an exception seems like the most sensible alternative. Your best bet would be to create your own, custom Exception class.

The code should look just about the same either way:

try {
    SearchResult someResult = searchForStuff();
}
catch ( ResultNotFoundException rnfe ) {
    /* do stuff */
}


/* almost the same as this */

SearchResult someResult = searchForStuff();

if ( someResult == null ) {
    /* do stuff */
}
2012-04-05 21:56
by jahroy