Professional Documents
Culture Documents
inputStr = JOptionPane.showInputDialog(null,
prompt);
try {
int age = Integer.parseInt(inputStr);
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(null, “ ‘ “+
inputStr + “ ‘ is invalid\n” + “Please enter
digits only”);
}
public int getAge (String prompt) {
String inputStr; This statement is executed only
if no exception is thrown by
int age; parselnt.
boolean keepGoing = true;
while (keepGoing) {
inputStr = JOptionPane.showInputDialog (null, prompt);
try {
age = Integer.parseInt (inputStr);
keepGoing = false; //input okay so stop looping
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog (null, “’” + inputStr + “’ is
invalid\n” + “Please enter digits only”);
} } return age; }
8.2 Throwing Exceptions and Multiple catch
Blocks
Compared to the original AgeInputVer1 class, the
AgeInputVer2 class is more robust because the
program does not terminate abruptly when an invalid
value is entered. However, the improved class is not
robust enough yet. There is still room for
improvements. For example, the current
implementation accepts invalid negative integers.
Since negative age is not possible, let’s improve the
code to take care of the invalid input of negative
integers.
Notice that a negative integer is an integer, so the
parseInt method will not throw an exception. We will
define the third class, AgeInputVer3, to throw (and
catch) an exception when the invalid input of a
negative integer is detected. Here’s the while loop of
the modified getAge method of the AgeInputVer3
class.
whle (true) {
inputStr = JOptionPane.showInputDialog(null, prompt);
try { age = Integer.parseInt(inputStr);
if (age < 0) { throw new Exception (“Nagative age is
invalide”);
} return age; //input OK so return the value & exit
} catch (NumberFormat Exception e) {
JOptionPane.showMessagedialog(null, “ ’ ” +
inputStr + “ ‘ is invalid\n” + Please enter digits
only”); } catch (Exception e) {
JOptionPane.showMessageDialog(null, “Error:” +
e.getMessage () ); } }
Exception No exception
Assume <t-stmt-3> throws an exception
and <catch-block-3> is the matching
catch block
try { try {
<t-stmt-1> <t-stmt-1>
<t-stmt-2> <t-stmt-2>
<t-stmt-3> <t-stmt-3>
<t-stmt-4> <t-stmt-4>
… …
<t-stmt-n> <t-stmt-n>
} }
<catch-block-1> <catch-block-1>
<catch-block-2> <catch-block-2>
<catch-block-3> <catch-block-3>
<catch-block-4> <catch-block-4>
… …
<catch-block-5> <catch-block-5>
Call sequence
Method A Method B Method C Method D
Catcher Propagator Propagator
Stack trace
D
C C
B B B
A A A A
Method A calls method B, method B in turn calls method
C, and so forth. Notice the stack trace in the figure.
Every time a method is executed, the method’s name is
placed on top of the stack. By the time method D is
executed, we have A, B, C, and D in the stack. When an
exception is thrown, the system searches down the
stack from the top, looking for the first matching
exception catcher. Method D throws an exception, but
no matching catch block exists in the method, so
method D is an exception propagator. The system then
checks method C. This Method is also an exception
propagator. Finally, the system locates the matching
catch block in method B, and therefore, method B is
the catcher for the exception thrown by method D.
Method A also includes the matching catch block, but
it will not be executed because the thrown exception is
already caught by method B, and method B does not
propagate this exception. Although the techique is not
used often, an exception catcher can also be set to
propagate the caught exception. For example, if we
rewrite method B as:
try {
C ();
} catch (Exception e) {………. //do something here
throw e; // propagate the caught exception to the
//method below this one in the trace stack
}
it is both a catcher and propagator. With modified
method B, method A’s matching catch block will get
executed, because method B, in addition to handling
the exception, throws the same exception, causing the
system to look for a matching catcher down the stack.
We have one last detail to complete the description of
the exception propagation mechanism. If a method is
an exception propagator, we need to modify its word
throws for this type of exceptions the method
propagators. We use the reserved word throws for
declaration. Methods C and D must have the follwing
declaration:
void C () throws Exception { …………….}
void D() throws Exception { …………….}
AgeInputVer4.java
8.4 Types of Exceptions
There are two types of exceptions: checked and
unchecked. A checked exception is an exception that is
checked at compile time. All other exceptions are
unchecked exceptions, also called runtime exceptions,
because they are unchecked at compile time and are
detected only at runtime.
Caller A (catcher)
Void callerA ( ) {
Try {
doWork ( );
} catch (RuntimeException e) {…….}
Caller C (propagator)
Void callerC ( ) {
……………. This is the most common style of
doWork ( ); runtime exceptions. Notice that
…………………..} caller C is a propagator implicityly.
8.5 Programmer-Defined Exception
Let’s define a class anmed AgeInputException as a
sebclass of the Exception class. To provide useful
information to the client, we will define the class so
the instances will carry three pieces of information:
lower bound, upper bound, and the value entered by
the user (in addition to the message inherited from the
Exception class). We will define three public methods
to access these data. Here’s the class definition:
AgeInputException.java
8.6 Assertionos
In this section we will describe a Java assertion and
explain how to use it effectively in our programs. A Java
assertion is a language feature we use to detect logical
errors in a program. We will illustrate the key points
with a very simple class that includes a logical error.
Because the sample class is simple, the use of assertion
may not seem so helpful. Keep in mind that this class is
for illustrative purposes only. The real benefit of using
the assertion feature becomes obvious when the
program logic gets more complex and the number of
classes in the program increases.
Here’s a bank account class that allows withdrawals
and deposits. There’s one logical error in the class.
class BankAccount {
private double balance;
public BankAccount (double initialBalance) {
balance = initialBalance;
}
public void deposit (double amount) {
double oldB alance = balance;
balance -= amount; Here’s a logical error. We
should add the amount.
assert balance > oldBalance;
}
public void withdraw (double amount) {
double oldBalance = balance;
balance -= amount;
If this boolean expression
assert balance < oldBalance; result in false, then an
} AssertionError is thrown.