Since you are a self-proclaimed "newbie", I think it would be a good idea to point out some broader issues with your code. (I know it is not production code, but just lets assume for the sake of argument that it was.)
If an exception is expected, it is usually simpler, clearer and more efficient if you detect the condition that will give rise to the exception. In this case, if you expect divisor
to occasionally be zero it is better to test it before doing the division.
On the other hand, if an exception is totally unexpected (i.e. a "bug") the best strategy is to let the exception propagate to the outermost level. At that point your application catch should catch all exceptions, log the exception stacktrace and bail out.
Apart from the previous bullet, it is a bad idea to catch Exception
, RuntimeException
, Throwable
or Error
. Doing this will catch a large number of exceptions that you probably don't intend to catch. In this case, since you are expecting an ArithmeticException
, you should catch just that.
It is rarely correct to use float
or double
in financial applications. These types are not exact, but financial applications typically require quantities of money to be handled exactly.
More generally, floating point numbers are inherently hard for lay people (and newbies) to understand. A lot of the "truths" that people expect to hold actually don't hold. For example, a floating point calculation of 1.0/3.0 + 1.0/3.0 + 1.0/3.0
does not give 1.0
. Similarly (as you discovered) division by zero behaves differently. If you want to use floating point safely, you need to understand the pitfalls.
EDIT elaborating the first point in response to @Jay's comment.
First, I deliberately used the word "usually". There are cases where avoiding throwing the expected exception achieves nothing.
Having said that, you often don't want a generic "expected" exception to happen even if your application cannot deal with the situation immediately. For example, if the OP's code was part of something larger, it may be better to explicitly throw IllegalArgumentException
(if this is a violation of an API contract) or some checked UserEnteredRubbishException
if we know that this is a result of bad user input (and there is some opportunity to report / correct it).
The fact that we are "expecting" an exception means by definition that we know more about it than (say) a generic ArithmeticException
would say. If we allow a generic exception to propagate, it makes it harder for a catch block many stack frames to act appropriately. In this case for example, the remote catch block could not diagnose the cause of the divide-by-zero with any certainty. The ArithmeticException
might have come from a different part of the application, and might not even be a divide-by-zero! The way to address is to explicitly throwing a more specific exception.