I think it is accepted that as a general rule in Java (and perhaps any language with exception handling) one should try to avoid using exception handling to actually handle
There is a reason exceptions are objects. There is also a reason designers of the Java language split all Throwable
s into 2 main types: checked and unchecked.
is it a good idea to rely on an exception happening for certain business logic to occur?
Yes. Absolutely. You should read Chapter 9 of "Effective Java, Second Edition". It's all there. Nicely explained and waiting for you.
If you are dealing with an error condition which is actually a part of the business logic, it is OK to use Exceptions. For example:
try{
// register new user
if(getUser(name) != null)
throw new MyAppException("Such user already exists");
//other registration steps......
}catch(MyAppException ex){
sendMessage(ex.getMessage());
}
This is really a discussion question, and the answer depends on the design of your system.
My instinct is always a blanket never, but i've seen several systems implement business errors using exceptions. I personally find it disgusting, but I really understand the advantage of breaking a business process as soon as you know that it failed, handling your failure ( e.g. rolling back your Unit Of Work), and returning the error to the caller, perhaps with added information.
one possible disadvantage, is that it's really straightforward to do the error handling across several different classes, so that the definition of what happens when the process fails is really hard to deduce from the code.
Anyway there is no single answer here, you need to weigh both approaches, and sometimes combine them.
regarding your example, I don't see any advantages for using exceptions for flow control, especially in a "good" (designed to work) scenario.
Whenever the exception can be anticipated but not avoided.
Say, if you are relying on an external API of some sort to parse data, and that API offers parse methods but nothing to tell whether a given input can be parsed or not (or if whether the parse can succeed or not depends on factors out of your control, but the API doesn't provide appropriate function calls), and the parsing method throws an exception when the input cannot be parsed.
With a properly designed API, this should boil down to a quantity somewhere in the range "virtually never" to "never".
I can see absolutely no reason to use exception handling as a means of normal flow control in code. It's expensive, it's hard to read (just look at your own first example; I realize it was probably written very quickly, but when _map
hasn't been initialized, what you end up with is an empty map, throwing away the entry you were trying to add), and it litters the code with largely useless try-catch blocks, which can very well hide real problems. Again taking your own example, what if the call to _map.add()
were to throw a NullPointerException
for some reason other than _map
being null
? Suddenly, you are silently recreating an empty map rather than adding an entry to it. Which I'm sure I don't really have to say can lead to any number of bugs in completely unrelated places in the code because of unexpected state...
Edit: Just to be clear, the above answer is written in the context of Java. Other languages may (and apparently, do) differ in the implementation expense of exceptions, but other points should still hold.
Throwing an exception is a relatively expensive operation in C++, and an extremely expensive one in Java. On efficiency grounds alone, it never makes sense to avoid an explicit check and accept an exception instead. I suppose you might be able to justify it in some rare cases where checking whether an exception would be thrown is very complex or nearly impossible, but otherwise, I'd say the answer is "pretty much never."