Transcript 20.ppt

CS110 Lecture 20
Tuesday, April 13, 2004
• Announcements
– hw9 due Thursday, April 15
– exam Tuesday, April 27
• Agenda
– Questions
– Error handling (JOI Chapter 7 finally!)
Lecture 20
1
Error handling
Write code so that running program can
– recognize when an error has occurred
– tell someone
– do something sensible
public void withdraw( int amount )
{
if ( amount <= balance ) {
incrementBalance( - amount );
}
else {
// an error; what now … ?
}
}
Lecture 20
2
Help! What next … ?
• First idea: print a message
public void withdraw( int amount )
{
if ( amount <= balance ) {
incrementBalance( - amount );
}
else {
System.out.println(“sorry”);
}
}
Lecture 20
3
To print or not to print?
• Good first idea – but …
– in banking system, i/o uses the ATM, but here
atm.println( ) fails because BankAccount
object doesn’t know about ATM (and shouldn’t)
• In general, printing is a bad idea
• Better idea: tell someone,
not necessarily the user
Lecture 20
4
Tell your client: return a value
public boolean withdraw( int amount ){
if ( amount <= balance ) {
incrementBalance( - amount );
return true;
}
return false;
}
• Client tests:
if (! account.withdraw(amount) )
// print if appropriate
// else return failure to your client
• Client knows that something happened,
but not what happened
Lecture 20
5
Use better return value
public String withdraw( int amount ){
if ( amount <= balance ){
incrementBalance( - amount );
return “” // or null
}
return “insufficient funds”;
}
• Client tests return value, has more information
– can print, or parse, or return something to
whoever called it
Lecture 20
6
Return an int
• Some designs/languages use int return code
• C and Unix shell convention:
– return 0 when all goes well
– return some n > 0 to report an error
• Design encourages a message catalog:
– look up message String using return code as a
key (catalog might be an ArrayList)
– provide a catalog in user’s native language,
for internationalization (I18N)
• You could invent an Object to return
Lecture 20
7
Two System tricks
• If you must print, use System.err rather
than System.out
• System.err goes to screen even when
System.out is redirected with >
• Terminal class implements errPrintln as
well as println
• If you must shut down immediately:
if (trueDisaster)
System.exit(911);
operating system can check return code
from the JVM
Lecture 20
8
When you detect an error,
consider
• printing something
• returning something the client can examine
• setting the value of some global (class)
variable that a client can look at
• shutting the program down
• throwing an Exception a client can catch
Lecture 20
9
Error handling is painful
• Imagining all possible errors is tricky
– you routinely miss some until code breaks
– that’s why you have to test!
• Deciding what to do is often difficult
(particularly if original design did not plan
for handling errors)
• Error handling code
– spreads out over the whole program
– can make clean logic complicated and ugly
– often accounts for 1/4 to 1/3 of real software
Lecture 20
10
Exceptions
•
•
•
•
•
Java’s object oriented mechanism for error handling
more powerful, more flexible than using return
Java keywords try, catch, throw
in class:
banking system, JOI with Exceptions
for hw:
improve Exception handling in Juno 7
• Model
– in client: instead of testing a returned value
•try, hoping for the best
• prepare to pick up the pieces if necessary (catch)
– in code where the error may occur:
• detect error
• create a new Exception and throw it
Lecture 20
11
Exceptions (client side)
• In client code (for example, Bank.java)
try {
account.withdraw( amount ));
}
catch ( InsufficientFundsException e ) {
// look at e, take appropriate action
}
// processing continues
• If all goes well, catch block code never executes
• If withdraw method in BankAccount has a
problem it creates a new
InsufficientFundsException object and throws it,
to be caught here
Lecture 20
12
Exceptions (service provider)
• Thrown where error happens
(The idea in BankAccount.java, not real code …):
public int withdraw( int amount )
{
if ( amount > balance ) {
throw new InsufficientFundsException();
}
incrementBalance( -amount );
return amount;
}
Lecture 20
13
Real Bank example
• Suppose a customer tries to withdraw more
than is in her account.
• Eventually BankAccount.java line 143
executes:
if (newBalance < 0) {
throw new
InsufficientFundsException …
• Read code backward looking for messages
(method invocations) to trace methods that
are active at that moment in order to see
where that Exception is caught
Lecture 20
14
Who calls whom?
InsufficientFundsException thrown here (line 144)
• method
–
–
–
–
–
incrementBalance
withdraw
processTrans…
visit
main
class
BA.java
BA.java
Bank.java
Bank.java
Bank.java
line
144
77
173
96
450
caught in catch (line 204) after try (lines 161-203)
Lecture 20
15
Method invocation stack
• At any moment while a program is running you can
trace the sequence of active methods from the currently
executing statement back to main()
• That sequence is the method invocation stack
• It’s called the call stack in C - often in Java too
(because it’s easier to say)
• The call stack is dynamic, changing as the program runs
(the program itself is static - fixed at compile time)
Lecture 20
16
Stack
• The call stack
– grows each time a message invokes a method
– shrinks each time a method returns
• main() is always the first thing pushed on to the stack
and the last to pop off: when main is done the program
is done
• In CS a stack is a last in first out collection
– push adds an item to the stack
– pop removes one
• The call stack
– push a method when it’s invoked
– pop a method when it returns
Lecture 20
17
Exceptions and the stack
• When error detected (BA.java line 143):
if (newBalance < 0)
throw new
InsufficientFundsException …
• Normal flow control stops - JVM looks for
the nearest catch, which may be
– in the running method
– somewhere up the call stack
Lecture 20
18
Going back through the stack
• incrementBalance throws an InsufficientFundsException
and does not catch it (no try block here)
• The incrementBalance message was sent from
BankAccount withdraw method,
which doesn’t catch the Exception either (no try block)
• The withdraw message was sent from Bank
processTransactionsForAccount method – inside a try
block. So control transfers to the matching catch block,
which handles the Exception
Lecture 20
19
Keyword throws – lawyers at work
private final void incrementBalance( int amount )
throws InsufficientFundsException
{
if ( ) throw new InsufficientFundsException();
}
• Since incrementBalance might throw an
InsufficientFundsException and (if it does) it
does not catch it, it must declare its intention to
throw it on up the stack to its caller by asserting
throws InsufficientFUndsException
• throws means might throw, not does throw
Lecture 20
20
Keyword throws – lawyers at work
public int withdraw( int amount )
throws InsufficientFundsException
{
incrementBalance( -amount );
}
• Since withdraw might see an
InsufficientFundsException thrown by
incrementBalance it must
– catch it // it doesn’t
– or declare its intention to throw it on up the stack to its
caller by asserting throws
InsufficientFUndsException
Lecture 20
21