516

I am using java language,I have a method that is supposed to return an object if it is found.

If it is not found, should I:

  1. return null
  2. throw an exception
  3. other

Which is the best practise or idiom?

bowman han
  • 1,010
  • 12
  • 22
Robert
  • 11,820
  • 19
  • 61
  • 85
  • 60
    Whatever you do, make sure you document it. I think this point is more important than exactly which approach is "best". – Rik Oct 06 '08 at 23:04
  • 6
    This depends on the prevailing idioms of the programming language. Please tag this question with a programming language tag. – Teddy Oct 01 '09 at 22:41
  • 3
    Returning null may only mean success or failure which very often isn't much of information (some methods may fail in many ways). Libraries should better throw exceptions to make errors explicit and this way the main program can decide how to handle the error on a higher level (in contrast to builtin error handling logic). – 3k- Aug 20 '13 at 11:33
  • 2
    Seems to me that the real question being asked is if we should consider it exceptional for an entity to be not found, and if so, why? No one really answered sufficiently how to come to that conclusion, and now the Q&A is closed. A real shame that the industry hasn't come to consensus on this important topic. Yes, I know it *depends*. So, explain why it depends with more than "if exceptional, throw" – crush Aug 09 '18 at 16:19

36 Answers36

498

If you are always expecting to find a value then throw the exception if it is missing. The exception would mean that there was a problem.

If the value can be missing or present and both are valid for the application logic then return a null.

More important: What do you do other places in the code? Consistency is important.

Ken
  • 2,054
  • 1
  • 19
  • 16
  • 30
    @Ken: +1, it would be nice to mention that if you do throw an exception, but can detect it a priori (like HasItem(...)), then the user should provide said Has* or Contains method. – user7116 Oct 06 '08 at 22:29
  • If you throw exceptions in model methods, it forces the developer to develop try/catch blocks from the calling scope, which ensures that the routines calling those model methods are handled properly from that scope. Otherwise, the developer could do whatever they want. Consider it an interface for calling model methods, if you will. If the data is not there, it's likely you will have to do some workaround anyway. – axiom82 May 30 '14 at 18:50
  • 4
    Instead of returning a value or null when the value is missing, consider returning a Maybe. See http://mikehadlow.blogspot.nl/2011/01/monads-in-c-5-maybe.html. – Erwin Rooijakkers Sep 29 '15 at 10:07
  • 2
    In a @ErwinRooijakkers _design choice way_, as of Java 8 you could also return an [Optional](https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html) – José Andias Jan 27 '16 at 15:27
  • In the face of ambiguity, it is tempting to pick one approach and stick with it consistently. I think we have to think carefully which one is more appropriate and judge it on a case-by-case basis. Contextually similar cases can then be treated in a consistent way, and determining the context goes beyond looking at return types. – Kevin Lee Sep 08 '16 at 05:25
  • 3
    I find it a bit disturbing every answer echoes the same proverb: "If it's exceptional, throw." Most engineers are going to be familiar with this principle. In my opinion, the real question here is how to determine if it *should be* considered exceptional. The OP is looking for the *best practice* in regards to something like a repository pattern for example. Is it typically considered exceptional for an object not to exist given a primary key? Yes, that is something his domain will determine, but what do most experts with years of experience suggest? That's the type of answer we should see. – crush Aug 09 '18 at 16:05
  • That question is really a matter of opinion it seems. People talk about remaining consistent, but the answers here aren't even consistent. Some seem to think it's proper to throw, while others think you should return a null. And so while your team's project may stay consistent, the moment you start using someone else's library, you may be facing inconsistency because no clear industry requirements for this common scenario have been defined. "If the value can be missing or present and both are valid...return null" I'd follow this up with the Q how should one determine if both are valid? – crush Aug 09 '18 at 16:14
  • 4
    @crush I think a guiding principal is _what parameters are passed to the function_. If you pass an _identity_, like you mention a primary key, then it should be considered exceptional if that item is not found, _because_ it indicates an inconsistent state in the system. Example: `GetPersonById(25)` would throw if that person has been deleted, but `GetPeopleByHairColor("red")` would return an empty result. So, I think the parameters say something about the expectations. – John Knoop Nov 01 '18 at 14:40
  • Consistency is important! – Yan Khonski Feb 01 '19 at 15:25
101

Only throw an exception if it is truly an error. If it is expected behavior for the object to not exist, return the null.

Otherwise it is a matter of preference.

Carlton Jenke
  • 2,897
  • 3
  • 24
  • 29
  • 4
    I don't agree. You can throw exceptions as status codes: "NotFoundException" – ACV Oct 16 '17 at 13:37
  • It certainly shouldn't be a matter of preference. That's how we end up with inconsistent code - if not among your team's code, then almost certainly when intertwining other developers code with your own (external libraries). – crush Aug 09 '18 at 16:21
  • 4
    I think handling the null case is much easier than "NotFoundException". Think about how many lines of try-catch you have to write around every single retrival request that throws a "NotFoundException"... It's painful to ready all that code in my eyes. – visc Aug 09 '18 at 20:05
  • i would like to quote Tony Hoare: "I call it my billion-dollar mistake". I would not return null, i either throw an exception and handle it correctly, or return an empty object. – seven Sep 09 '19 at 13:12
72

As a general rule, if the method should always return an object, then go with the exception. If you anticipate the occasional null and want to handle it in a certain way, go with the null.

Whatever you do, I highly advise against the third option: Returning a string that says "WTF".

Matias Nino
  • 4,165
  • 13
  • 44
  • 62
  • Plus one because in the good old days i did that more than a couple of times as a quick dirty "temporal" fix... no good idea. Specially if its going to be reviewed if you are a student. – rciafardone Mar 13 '14 at 15:48
  • 17
    I was going to down vote since the WTF options seemed awesome to me...but apparently I have a heart – swestner Sep 23 '15 at 20:45
  • 9
    throw new WtfExceptin – Kamafeather Jan 16 '18 at 00:41
  • I think it would be helpful if this answer talked about reasons why a method would always return an object versus "an occasional null". What warrants that type of situation? Give an example of when such a circumstance might exist. – crush Aug 09 '18 at 16:23
51

If null never indicates an error then just return null.

If null is always an error then throw an exception.

If null is sometimes an exception then code two routines. One routine throws an exception and the other is a boolean test routine that returns the object in an output parameter and the routine returns a false if the object was not found.

It's hard to misuse a Try routine. It's real easy to forget to check for null.

So when null is an error you just write

object o = FindObject();

When the null isn't an error you can code something like

if (TryFindObject(out object o)
  // Do something with o
else
  // o was not found
Kevin Gale
  • 3,980
  • 6
  • 28
  • 31
  • 1
    This would be a more useful suggestion if C# provided real tuples, so we could avoid using an [out] parameter. Still, this is the preferred pattern, so +1. – Erik Forbes Oct 06 '08 at 19:07
  • 2
    In my opinion, the try approach is the best one. You don't have to look up then what happens if the object cannot be returned. With a Try method, you immediately know what to do. – OregonGhost Oct 06 '08 at 20:52
  • reminds me the `find` and `findOrFail` from Laravel Eloquent – javier_domenech May 31 '18 at 12:00
  • @ErikForbes I know your comment is old, but wouldn't the answer have been to define a multi-property object that would be returned from the `TryFindObject` method? Tuples seem more of a lazy paradigm for programmers who don't want to take the time to define an object that encapsulates multiple values. That is essentially all tuples are at the core anyways. – crush Aug 09 '18 at 16:26
  • @crush - Named Tuple Literals are an option, IMO. This is a link to an async Try Get pattern with tuples. https://stackoverflow.com/questions/1626597/should-functions-return-null-or-an-empty-object/51565145#51565145#answer-51565145 – ttugates Apr 09 '19 at 00:10
27

I just wanted to recapitulate the options mentioned before, throwing some new ones in:

  1. return null
  2. throw an Exception
  3. use the null object pattern
  4. provide a boolean parameter to you method, so the caller can chose if he wants you to throw an exception
  5. provide an extra parameter, so the caller can set a value which he gets back if no value is found

Or you might combine these options:

Provide several overloaded versions of your getter, so the caller can decide which way to go. In most cases, only the first one has an implementation of the search algorithm, and the other ones just wrap around the first one:

Object findObjectOrNull(String key);
Object findObjectOrThrow(String key) throws SomeException;
Object findObjectOrCreate(String key, SomeClass dataNeededToCreateNewObject);
Object findObjectOrDefault(String key, Object defaultReturnValue);

Even if you choose to provide only one implementation, you might want to use a naming convention like that to clarify your contract, and it helps you should you ever decide to add other implementations as well.

You should not overuse it, but it may be helpfull, espeacially when writing a helper Class which you will use in hundreds of different applications with many different error handling conventions.

Lena Schimmel
  • 6,934
  • 5
  • 41
  • 56
  • I like the clear function names, especially orCreate and orDefault. – marcovtwout Jul 14 '15 at 09:10
  • 5
    Most of this can be more cleanly written with `Expected findObject(String)` where `Expected` has the functions `orNull()`, `orThrow()`, `orSupplied(Supplier supplier)`, `orDefault(T default)`. This abstracts the getting of the data from the error handling – WorldSEnder Oct 06 '15 at 02:39
  • I didn't know about Expected until now. I seems to be pretty new and might not have existed when I wrote the original answer. Maybe you should make your comment a proper answer. – Lena Schimmel Oct 06 '15 at 11:57
  • Also, Expected is a C++ template. Are there implementations of it in other object oriented languages as well? – Lena Schimmel Oct 06 '15 at 11:58
  • In Java 8, returning Optional (called Maybe, etc. in other languages) is an option as well. This clearly indicates to the caller that returning nothing is a possibility, and won't compile if the caller hasn't handled that possibility, as opposed to null, which (in Java anyway) will compile even if the caller doesn't check it. – Some Guy Jan 22 '19 at 12:54
18

Use the null object pattern or throw an exception.

pmlarocque
  • 1,744
  • 1
  • 18
  • 26
  • This is the real answer. Returning null is a terrible habit of lazy programmers. – jeremyjjbrown May 23 '13 at 19:01
  • I can't believe this answer hasn't been voted to the top yet. This IS the real answer, and either approach is dead-easy and saves a lot of code-bloat or NPEs. – Bane Sep 06 '13 at 13:16
  • http://sourcemaking.com/design_patterns/null_object – Bane Sep 06 '13 at 13:35
  • 3
    If one uses the null object pattern, how would one distinguish the case where the key is mapped to the null object from the case where the key has no mapping? I would think returning a meaningless object would be far worse than returning null. Returning null to code that's not prepared to handle it will generally result in an exception being thrown. Not the optimal choice of exception, but an exception nonetheless. Returning a meaningless object is more likely to result in the code incorrectly regarding meaningless data as correct. – supercat Oct 04 '14 at 22:25
  • 3
    How would the null object behave for an entity lookup? E.g., `Person somePerson = personRepository.find("does-not-exist");` Let's assume this method returns a null object for ID `does-not-exist`. What would then be the correct behavior for `somePerson.getAge()`? Right now, I'm not yet convinced the null object pattern is the right solution for entity lookups. – Abdull Jun 15 '15 at 15:23
  • That why I said OR throw an exception, if it does not make sense in your case to propagate a NullPerson. In fact, I think that for entity lookups the best approach is to throw, then your controller/service/model/whatever will catch it and decide if it rethrow or return a null object. But yes your data access layer should throw, exceptions are easier to catch/debug than wondering why you have a null somewhere in the chain. – pmlarocque Jun 15 '15 at 18:45
  • @supercat The null object should be on a different inheritance branch e.g. RealRecord : RecordBase and NullRecord : RecordBase. Then anything taking a RealRecord can't possibly take a NullRecord. RecordBase communicates it could be either be real or null, and should itself be abstract. – Samuel Danielson Apr 26 '20 at 15:02
  • @SamuelDanielson: One of the major reasons that nulls are useful is that there needs to be a way of representing the state of an array element which hasn't been written yet, and it's useful to have a way of copying the state of array elements that may or may not have been written. If one wanted to have an array pre-populated so every item contains a `NullRecord`, all code that attempts to read the array would have to convert a `RecordBase` reference to a `RealRecord` reference, failing if the item is actually a `NullRecord`, and I don't see what one would have gained. – supercat Apr 26 '20 at 15:14
  • @supercat I didn't see a language tag in the question. C++, C#, and Rust use the word "Default" in their standard libraries to differentiate from Null in that case. If we actually look at our options across many languages we can express errors with exceptions, sentinels, defaults, nulls, sum types, unions, tagged unions, folded unions, product types (isValid? attribute), etc. I guess it just depends on how much you want the type system to help, and how much errors should be allowed to extend a module's unchecked interface. – Samuel Danielson Apr 26 '20 at 15:42
  • @SamuelDanielson: If one wants to be able to have a `T[]` with an arbitrary generic type `T`, allow elements to be read in cases where can't be *statically proven* to have been written, and define the behavior of such a read, then it must define a default state for array items that haven't been written yet. C# provides a uniform syntax to refer to the default value of any arbitrary `T`; for reference types, it yields null; for numeric types, it's zero; for structure types, it yields a structure with all fields holding default values. – supercat Apr 26 '20 at 17:36
13

Be consistent with the API(s) you're using.

S.Lott
  • 359,791
  • 75
  • 487
  • 757
dmckee --- ex-moderator kitten
  • 90,531
  • 23
  • 129
  • 225
13

it depends if your language and code promotes: LBYL (look before you leap) or EAFP (easier to ask forgiveness than permission)

LBYL says you should check for values (so return a null)
EAFP says to just try the operation and see if it fails (throw an exception)

though I agree with above.. exceptions should be used for exceptional/error conditions, and returning a null is best when using checks.


EAFP vs. LBYL in Python:
http://mail.python.org/pipermail/python-list/2003-May/205182.html (Web Archive)

Caramiriel
  • 5,981
  • 2
  • 25
  • 45
Corey Goldberg
  • 53,391
  • 24
  • 118
  • 137
  • 3
    In some cases, EAFP is the only meaningful approach. In a concurrent map/dictionary, for example, there's no way to ask whether a mapping will exist when it is requested. – supercat Oct 04 '14 at 22:26
13

Just ask yourself: "is it an exceptional case that the object is not found"? If it is expected to happen in the normal course of your program, you probably should not raise an exception (since it is not exceptional behavior).

Short version: use exceptions to handle exceptional behavior, not to handle normal flow of control in your program.

-Alan.

AlanR
  • 1,152
  • 4
  • 14
  • 26
13

Advantages of throwing an exception:

  1. Cleaner control flow in your calling code. Checking for null injects a conditional branch which is natively handled by try/catch. Checking for null doesn't indicate what it is you're checking for - are you checking for null because you're looking for an error you're expecting, or are you checking for null so you don't pass it further on downchain?
  2. Removes ambiguity of what "null" means. Is null representative of an error or is null what is actually stored in the value? Hard to say when you only have one thing to base that determination off of.
  3. Improved consistency between method behavior in an application. Exceptions are typically exposed in method signatures, so you're more able to understand what edge cases the methods in an application account for, and what information your application can react to in a predictable manner.

For more explanation with examples, see: http://metatations.com/2011/11/17/returning-null-vs-throwing-an-exception/

  • 2
    +1 because point 2 is excellent - null does not have the the same meaning as not found. This become more important when dealing with dynamic languages where Null could actually be the object being stored/retrieved by the function - and in that case – Adam Terrey Oct 13 '15 at 04:17
  • 1
    +1 for point #2. Is null an error? Is null what is stored for the given key? Is null indicative that the key does not exist? These are the real line of questions that make it clear returning null is almost never correct. This is likely the best answer here as everyone else has just been throwing up the ambiguous "If it's exceptional, throw" – crush Aug 09 '18 at 16:37
  • Exceptions may incur a performance penalty compared to returns (e.g. in Java), though. And unchecked exceptions (e.g. in Java) may surface in unintended places. – tkruse Nov 19 '20 at 04:54
6

Exceptions are related to Design by Contract.

The interface of an objects is actually a contract between two objects, the caller must meet the contract or else the receiver may just fail with an exception. There are two possible contracts

1) all input the method is valid, in which case you must return null when the object is not found.

2) only some input is valid, ie that which results in a found object. In which case you MUST offer a second method that allows the caller to determine if its input will be correct. For example

is_present(key)
find(key) throws Exception

IF and ONLY IF you provide both methods of the 2nd contract, you are allowed to throw an exception is nothing is found!

akuhn
  • 25,901
  • 2
  • 72
  • 86
4

Depends on what it means that the object is not found.

If it's a normal state of affairs, then return null. This is just something that might happen once in an while, and the callers should check for it.

If it's an error, then throw an exception, the callers should decide what to do with the error condition of missing object.

Ultimately either would work, although most people generally consider it good practice to only use Exceptions when something, well, Exceptional has happened.

Steve B.
  • 49,740
  • 11
  • 90
  • 128
  • 2
    How would you elaborate on the "_normal state of affairs_" statement and what criteria will you use to distinguish it with an error. – user1451111 Jun 14 '18 at 13:46
4

Here are a couple more suggestions.

If returning a collection, avoid returning null, return an empty collection which makes enumeration easier to deal with without a null check first.

Several .NET API's use the pattern of a thrownOnError parameter which gives the caller the choice as whether it is really an exceptional situation or not if the object is not found. Type.GetType is an example of this. Another common pattern with BCL is the TryGet pattern where a boolean is returned and the value is passed via an output parameter.

You could also consider the Null Object pattern in some circumstances which can either be a default or a version with no behaviour. The key is avoid null checks throughout the code base. See here for more information http://geekswithblogs.net/dsellers/archive/2006/09/08/90656.aspx

Duncan
  • 2,363
  • 1
  • 16
  • 13
3

I prefer to just return a null, and rely on the caller to handle it appropriately. The (for lack of a better word) exception is if I am absolutely 'certain' this method will return an object. In that case a failure is an exceptional should and should throw.

swilliams
  • 44,959
  • 24
  • 94
  • 129
3

Return a null instead of throwing an exception and clearly document the possibility of a null return value in the API documentation. If the calling code doesn't honor the API and check for the null case, it will most probably result in some sort of "null pointer exception" anyway :)

In C++, I can think of 3 different flavors of setting up a method that finds an object.

Option A

Object *findObject(Key &key);

Return null when an object can't be found. Nice and simple. I'd go with this one. The alternative approaches below are for people who don't hate out-params.

Option B

void findObject(Key &key, Object &found);

Pass in a reference to variable that will be receiving the object. The method thrown an exception when an object can't be found. This convention is probably more suitable if it's not really expected for an object not to be found -- hence you throw an exception to signify that it's an unexpected case.

Option C

bool findObject(Key &key, Object &found);

The method returns false when an object can't be found. The advantage of this over option A is that you can check for the error case in one clear step:

if (!findObject(myKey, myObj)) { ...
Ates Goral
  • 126,894
  • 24
  • 129
  • 188
3

In some functions I add a parameter:

..., bool verify = true)

True means throw, false means return some error return value. This way, whoever uses this function has both options. The default should be true, for the benefit of those who forget about error handling.

Lev
  • 5,897
  • 5
  • 24
  • 29
3

referring only to the case where null is not considered an exceptional behavior i am definitely for the try method, it is clear, no need to "read the book" or "look before you leap" as was said here

so basically:

bool TryFindObject(RequestParam request, out ResponseParam response)

and this means that the user's code will also be clear

...
if(TryFindObject(request, out response)
{
  handleSuccess(response)
}
else
{
  handleFailure()
}
...
DorD
  • 153
  • 2
  • 12
2

If it's important for client code to know the difference between found and not found and this is supposed to be a routine behavior, then it's best to return null. Client code can then decide what to do.

plinth
  • 45,549
  • 9
  • 75
  • 118
2

Generally it should return null. The code calling the method should decide whether to throw an exception or to attempt something else.

Eran Galperin
  • 83,588
  • 23
  • 113
  • 132
2

Or return an Option

An option is basically a container class that forces the client to handle booth cases. Scala has this concept, look up it's API.

Then you have methods like T getOrElse(T valueIfNull) on this object thet either return the found object, or an allternative the client specifieces.

John Nilsson
  • 16,089
  • 8
  • 29
  • 41
2

Prefer returning null --

If the caller uses it without checking, the exception happens right there anyway.

If the caller doesn't really use it, don't tax him a try/catch block

kizzx2
  • 17,547
  • 14
  • 72
  • 81
2

Unfortunately JDK is inconsistent, if you trying access non existing key in resource bundle, you get not found exception and when you request value from map you get null if it doesn't exists. So I would change winner answer to the following, if found value can be null, then raise exception when it isn't found, otherwise return null. So follow to the rule with one exception, if you need to know why value isn't found then always raise exception, or..

Dmitriy R
  • 593
  • 1
  • 4
  • 11
1

If the method returns a collection, then return an empty collection (like sayed above). But please not Collections.EMPTY_LIST or such! (in case of Java)

If the method retrives a single object, then You have some options.

  1. If the method should always find the result and it's a real exception case not to find the object, then you should throw an exception (in Java: please an unchecked Exception)
  2. (Java only) If you can tolerate that the method throws a checked exception, throw a project specific ObjectNotFoundException or the like. In this case the compiler says you if you forget to handle the exception. (This is my preferred handling of not found things in Java.)
  3. If you say it's really ok, if the object is not found and your Method name is like findBookForAuthorOrReturnNull(..), then you can return null. In this case it is strongly recomminded to use some sort of static check or compiler check, wich prevents dereferencing of the result without a null check. In case of Java it can be eg. FindBugs (see DefaultAnnotation at http://findbugs.sourceforge.net/manual/annotations.html) or IntelliJ-Checking.

Be careful, if you decide to return a null. If you are not the only programmer in project you will get NullPointerExceptions (in Java or whatever in other Languages) at run time! So don't return nulls which are not checked at compile time.

iuzuz
  • 61
  • 6
  • Not if the code was properly written to expect `null`. See top-voted answer for more. – Andrew Barber Aug 21 '12 at 13:19
  • But only if you ensure at compile time, that all nulls are checked. This can be done, using FindBugs @NutNull at package level and mark your method as "may return null". Or to use a language like Kotlin or Nice. But it is much more simplier not to return null. – iuzuz Aug 21 '12 at 13:44
  • "Simpler", *maybe*. But often plain incorrect – Andrew Barber Aug 21 '12 at 13:46
  • Sorry, but what is incorrect if a method, which promises to find a book, can't find them and throws an exception? Do you know the "Billion Dollar Mistake"? http://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare – iuzuz Aug 21 '12 at 13:56
  • 1
    Again: Read the top-voted answer for more information. Basically: If it's a potentially-expected result that the book requested can't be found, an exception is the *wrong* thing to do when the requested book is simply not found, as opposed to some error occurring. – Andrew Barber Aug 21 '12 at 14:01
  • The top-voted answer must not be the only right. I disagree the answer. Also Robert C. Martin (in Clean Code: A Handbook of Agile Software Craftsmanshi) and Michael Feathers disagree. And new programming languages like Kotlin and Nice subscribe for the view. And. Perhaps I take it to heart too much, but why did you voted me down? I did not break a rule and my answer is not so bad. – iuzuz Aug 21 '12 at 15:35
  • 1
    You are misunderstanding a lot here. You are applying conditional advice universally, which is almost always a bad thing to do. Read the rest of the up voted answers, too. Your answer just states an absolute, and presents extremely faulty logic for it. – Andrew Barber Aug 21 '12 at 16:40
  • I have rewritten the answer. The previous answer was only for Java. – iuzuz Aug 22 '12 at 10:02
1

As long as it's supposed to return a reference to the object, returning a NULL should be good.

However, if it's returning the whole bloody thing (like in C++ if you do: 'return blah;' rather than 'return &blah;' (or 'blah' is a pointer), then you can't return a NULL, because it's not of type 'object'. In that case, throwing an exception, or returning a blank object that doesn't have a success flag set is how I would approach the problem.

warren
  • 28,486
  • 19
  • 80
  • 115
1

Don't think anyone mentioned the overhead in exception handling - takes additional resources to load up and process the exception so unless its a true app killing or process stopping event (going forward would cause more harm than good) I would opt for passing back a value the calling environment could interpret as it sees fit.

ScottCher
  • 13,371
  • 6
  • 24
  • 25
1

I agree with what seems to be the consensus here (return null if "not found" is a normal possible outcome, or throw an exception if the semantics of the situation require that the object always be found).

There is, however, a third possibility that might make sense depending on your particular situation. Your method could return a default object of some sort in the "not found" condition, allowing calling code to be assured that it will always receive a valid object without the need for null checking or exception catching.

GBegen
  • 5,979
  • 3
  • 29
  • 51
1

Return a null, exceptions are exactly that: something your code does that isn't expected.

Anders
  • 11,090
  • 34
  • 91
  • 142
1

Exceptions should be exceptional. Return null if it is valid to return a null.

Andrew Lewis
  • 4,575
  • 1
  • 26
  • 30
1

If you are using a library or another class which throws an exception, you should rethrow it. Here is an example. Example2.java is like library and Example.java uses it's object. Main.java is an example to handle this Exception. You should show a meaningful message and (if needed) stack trace to the user in the calling side.

Main.java

public class Main {
public static void main(String[] args) {
    Example example = new Example();

    try {
        Example2 obj = example.doExample();

        if(obj == null){
            System.out.println("Hey object is null!");
        }
    } catch (Exception e) {
        System.out.println("Congratulations, you caught the exception!");
        System.out.println("Here is stack trace:");
        e.printStackTrace();
    }
}
}

Example.java

/**
 * Example.java
 * @author Seval
 * @date 10/22/2014
 */
public class Example {
    /**
     * Returns Example2 object
     * If there is no Example2 object, throws exception
     * 
     * @return obj Example2
     * @throws Exception
     */
    public Example2 doExample() throws Exception {
        try {
            // Get the object
            Example2 obj = new Example2();

            return obj;

        } catch (Exception e) {
            // Log the exception and rethrow
            // Log.logException(e);
            throw e;
        }

    }
}

Example2.java

 /**
 * Example2.java
 * @author Seval
 *
 */
public class Example2 {
    /**
     * Constructor of Example2
     * @throws Exception
     */
    public Example2() throws Exception{
        throw new Exception("Please set the \"obj\"");
    }

}
svlzx
  • 192
  • 3
  • 11
  • If the exception to be thrown from the function is not a runtime exception, and the caller is expected to handle it (instead of just terminating the program), then instead of throwing an exception from an internal subsystem that the caller can't expect, it would be better to wrap the internal exception with an external checked exception, while 'chaining' the internal exception so that someone debugging can figure out why the external exception was thrown. For instance, example1 could use 'throw new MyCheckedException("Please set the \"obj\"", e)' to include 'e' in the thrown exception. – Some Guy Jan 22 '19 at 12:49
0

That really depends on if you expect to find the object, or not. If you follow the school of thought that exceptions should be used for indicating something, well, err, exceptional has occured then:

  • Object found; return object
  • Object not-found; throw exception

Otherwise, return null.

Rob
  • 43,549
  • 23
  • 115
  • 144
0

It depends on the nature of the method and how it will be used. If it is normal behavior that the object may not be found, then return null. If it is normal behavior that the object is always found, throw an exception.

As a rule of thumb, use exceptions only for when something exceptional occurs. Don't write the code in such a way that exception throwing and catching is part of its normal operation.

Simon Howard
  • 8,843
  • 4
  • 25
  • 21
0

If not finding it is an exceptional event (i.e. it should be there under normal circumstances), then throw. Otherwise, return a "not found" value (can be null, but does not have to), or even have the method return a boolean for found/notfound and an out parameter for the actual object.

Nemanja Trifunovic
  • 23,597
  • 3
  • 46
  • 84
0

That depends on your method. If you method is supposed to always return a valid object and none is found, throwing an exception is the way to go. If the method is just ment to return an object which might or might not be there (like perhaps a image on a contact person) you shouldn't raise an error.

You might also want to expose a method returning a boolean true/false if this method actually will return an object so you don't have to either a) check for null or b) catch an exception

Per Hornshøj-Schierbeck
  • 14,299
  • 19
  • 76
  • 100
0

The "other" option could be to let the find method take an additional parameter with a default object that would be returned if the sought for object cannot be found.

Otherwise I'd just return null unless it really is an exceptional case when the object isn't found.

Chris Vest
  • 8,334
  • 2
  • 32
  • 43
0

In data layer code, I some times use the following code, allowing the caller to decide if "object not found" means an error has occured.


DataType GetObject(DBConnection conn, string id, bool throwOnNotFound) {
    DataType retval = ... // find object in database
    if (retval != null || ! throwOnNotFound) {
        return retval;
    } else {
        throw new NoRowsFoundException("DataType object with id {id} not found in database");
    }
}

DataType GetObject(DBConnection conn, string id) {
    return GetObject(conn, id, true);
} 
codeape
  • 89,707
  • 22
  • 139
  • 171
0

It not containing the object can happen during normal operations and should be dealt with by the caller return NULL.

If not containing the object indicates a bug by the calling code or internal state then do an assert.

If not containing the object indicates an infrequent event. (Like someone deleted an item from the store while you were checking out the item at the same time.) Then throw an exception.

Jeroen Dirks
  • 7,142
  • 11
  • 47
  • 66