Java Reference
In-Depth Information
Sidebar 6.3 Dealing with exceptions
When dealing with exceptions it is important to remember that when an exception is thrown a
whole set of statements are skipped between the throw statement and the matching catch state-
ment. This is relatively easy to consider if the throw and catch statements are quite close, but it
can be easily overlooked, becoming a serious problem, when the exception propagates through
several methods.
If a method propagates an exception (generated either by the method itself or by some method
it calls), all the statements from the point where it is generated to the end of the method are
skipped.
Let's consider some examples of methods operating on bank accounts.
void
withdrawal(
double
amount){
try
{
subtract(amount); // can throw exception
// in the case of an exception the following statement is skipped
printConfirmation();
}
catch
(AmountNotAvailableException e){ //.. }
}
void
subtract(
double
amount)()
throws
AmountNotAvailableException {
if
(amount < available)
throw new
AmountNotAvailableException();
available -
#
amount;
//..
}
In the previous example the
subtract()
method throws an exception if
amount
is less than
avail-
able
, therefore the subtraction of
amount
from
available
is skipped.
The
withdrawal()
method calls
subtract()
, if subtract terminates normally then it prints a
confirmation, otherwise the call to
printConfirmation()
is skipped.
This use of exceptions allows us to write the sequence of operations in the ideal case and to
separate the handling of exceptional cases. It is important to consider carefully the order of
operations. Let's consider the following example:
void
transfer(
double
amount)
throws
AmountNotAvailableException {
destinationBankAccount.add(amount);
sourceBankAccount.subtract(amount); // can throw exception
}
If no exception is thrown, the above code appears to be correct. But the
subtract()
method can
throw an exception that is propagated to the caller of the
transfer()
method. When this happens the
amount is credited to the destination account, but no amount is withdrawn from the source
account: some money has magically appeared! The overall coherence of the accounts is lost.
To solve this problem the following code should be used instead:
void
transfer(
double
amount)
throws
AmountNotAvailableException {
sourceBankAccount.subtract(amount); // can throw exception
destinationBankAccount.add(amount);
}
In the absence of exceptions the overall effect of the method is the same, but if an exception is
thrown the
add()
method is skipped, preserving the overall coherence of the accounts.
As a general rule, extra attention must be paid when exceptions can be thrown in order to
preserve the coherence of the data.