Transcript Document

CS110 Lecture 21
Thursday, April 15, 2004
• Announcements
– hw9 due tonight
– hw9 due Thursday, April 22
– exam Tuesday, April 27
• Agenda
– Questions
– Error handling (continued)
• in Bank
• in Juno 7
Lecture 21
1
Exceptions
•
•
•
•
•
Java’s object oriented mechanism for error handling
more powerful, more flexible than using return
Java keywords try, catch, throw,throws
in class:
banking system, Juno with Exceptions
for hw:
improve Exception handling in Juno 7.5
• 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 21
2
Bank version 7
• 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 21
3
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 21
4
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)
• There will be a call stack question on the exam
Lecture 21
5
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 21
6
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 21
7
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 21
8
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 21
9
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 either
– catch it // it doesn’t
– or declare its intention to throw it on up the stack to its
caller by asserting
throws InsufficientFUndsException
Lecture 21
10
Exceptions in the Java API
• No throws cause needed for these, but you can
catch them if you suspect one may be thrown
• NoSuchElementException
– thrown for you by JVM when you try to ask for a
element after an Iterator is done
• NullPointerException
– thrown for you by JVM when you try to send a
message to an Object that does not exist
• ClassCastException
– thrown for you by JVM when you try to cast an
Object to a type it isn’t an instance of
• ArrayIndexOutOfBoundsException …
Lecture 21
11
Error handling in Juno 7
• JunoExceptions are caught in the try/catch in
CLIShell interpret lines 73-89
• Note how different kinds of Exceptions are dealt
with in order
• ExitShellException is thrown (only) by doIt in
LogoutCommand class
• BadShellCommandException knows what
command was bad so we can give help
• Catch a generic JunoException and print its
message
• Then deal with truly unexpected errors … catch
any Exception. At least Juno won’t crash.
Lecture 21
12
Error detection in Juno
• Errors detected in the various doIt methods
• doIt declaration in abstract ShellCommand class
says that it throws JunoException
• Example: TypeCommand.java, where we have
written all the error detection
Lecture 21
13
mars:> type # no filename
try {
filename = args.nextToken();
}
catch (NoSuchElementException e) {
throw
new BadShellCommandException( this );
}
• Catch JVM’s Exception and throw one of your own that
makes more sense in this application
Lecture 21
14
mars:> type foo
try {
// retrieve foo from current directory
// cast to TextFile and print contents
}
catch (NullPointerException e) {
// throw a JunoException
}
catch (ClassCastException e) {
// throw a JunoException
}
Lecture 21
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
• When a method throws an Exception the JVM looks for
a surrounding try block so it can resume execution in
the corresponding catch
• The search begins locally and works its way back
through the call stack
Lecture 21
16
Call stack
JunoExceptions may be thrown here
• method
–
–
–
–
–
–
–
–
doIt
interpret
CLIShell
constructor
interpret
CLILogin
constructor
main
class
next call on line
TypeCommand
Shell
Shell
Shell
LoginInterpreter
LoginInterpreter
Juno
Juno
74
50
41
89
60
66
190
caught in catch (line 79 or 83) after try (lines 73-75)
Lecture 21
17
Keyword throws – lawyers at work
public void doIt( ... )
throws JunoException
{
...
}
• Since doIt might throw a JunoException it must
– catch it // it doesn’t
– or declare its intention to throw it on up the stack to its
caller by asserting throws JunoException
• throws means might throw, not does throw
• Built in Exceptions don’t need a throws clause
• If uncaught they crash the program
Lecture 21
18
RumpelStiltskin
• Exception examples in a short standalone program
• The fairy tale: guess my name
• examples/RumpelStiltskin.java
•
•
•
•
>
>
>
>
Java
Java
Java
Java
RumpelStiltskin
RumpelStiltskin foo
RumpelStiltskin foo bar
RumpelStiltskin RumpelStiltskin
Lecture 21
19
Java RumpelStiltskin
• Design (pseudocode)
If there is no command line argument
print usage message
end the program
• Two possible implementation strategies
– test for args[0], proceed based on test result
– assume args[0] is there, catch Exception if not
Lecture 21
20
Test first strategy
if (args.length == 0 ) {
System.out.println(
"usage: java RumpelStiltskin guess");
System.exit(0); // leave program gracefully
}
// continue normal processing
Lecture 21
21
Exception strategy
try {
System.out.println(”Are you " + args[0] +'?');
rumpelstiltskin.guessName(args[0]);
System.out.println("Yes! How did you guess?");
System.exit(0); // leave program gracefully
}
// come here right away if there is no args[0]
catch (IndexOutOfBoundsException e) {
System.out.println(
"usage: java RumpelStiltskin guess");
System.exit(0); // leave program gracefully
}
Lecture 21
22
java RumpelStiltskin foo
sorry - foo is not my name
Intentionally generate a NullPointerException,
see what the Exception's toString method returns
java.lang.NullPointerException
Experiment with the printStackTrace() method:
BadGuessException
at java.lang.Throwable.<init>(Compiled Code)
at java.lang.Exception.<init>(Compiled Code)
at BadGuessException.<init>(Compiled Code)
at Wizard.guessName(Compiled Code)
at Wizard.makeMischief(Compiled Code)
at RumpelStiltskin.main(Compiled Code)
Look for a second command line argument,
see what happens if it's not there:
java.lang.ArrayIndexOutOfBoundsException: 1
at RumpelStiltskin.main(Compiled Code)
Lecture 21
23
hw10
• Add error handling to register and login
• Error detection for all shell commands
• Count fraction of Juno that’s there for error
handling
Lecture 21
24