Exception - Department of Computing Science

Download Report

Transcript Exception - Department of Computing Science

Revised 12/16/99
Exceptions
Cmput 115 - Lecture 3
Department of Computing Science
University of Alberta
©Duane Szafron 1999
Some code in this lecture is based on code from the book:
Java Structures by Duane A. Bailey or the companion structure package
2
About This Lecture

In this lecture we learn how to use Java
Exceptions to handle unusual program
conditions. Note, this material is not in
the text book.
©Duane Szafron 1999
3
Outline

Assertions and generic exceptions

Throwables, Errors and Exceptions

Throwing exceptions

Catching exceptions

Exception matching

User-defined Throwable classes

Multiple catch clauses and the finally clause
©Duane Szafron 1999
4
Exceptions - Failed Assertions

An assertion is a condition that should be true.

What happens if the assertion fails?

One option is to report that the assertion has failed and to
halt the program. (Preventive Approach)

Alternately, the programmer can signal that an unusual
event has occurred and call some code to handle the
special case. (Corrective Approach)

In general, these special cases are generically called
Exceptions.
©Duane Szafron 1999
5
Quick Example

Want to determine the number of pretzels
per glass of beer
Enter number of pretzels:
12
Enter number of glasses of beer:
5
12 pretzels
5 glasses of beer
We have 2.4 pretzels for each glass of beer.
©Duane Szafron 1999
6
Quick Example

Want to determine the number of pretzels
per glass of beer
Enter number of pretzels:
13
Enter number of glasses of beer:
0
No Beer!
Go get some at RAT’s
Program aborted.
©Duane Szafron 1999
7
GotBeer (1 of 2)
Public class GotBeer
{ public static void main(String[ ] args)
{ int beerCount, pretzelCount;
double pretzelsPerGlass;
System.out.println(“Enter number of pretzels:”);
pretzelCount = Savit.readLineInt( );
System.out.println(“Enter number of glasses of beer:”);
beerCount = Savit.readLineInt( );
if (beerCount <= 0)
{ System.out.printlin(“No Beer!”);
Assert.condition(beerCount>0,
System.out.println(“Go
to RAT’s”);
“No Beer!\nGo
to RAT\’s\nProgramAborted”);
System.out.println(“Program Aborted”);
}
System.exit(0);
}
©Duane Szafron 1999
8
GotBeer (1 of 2)
pretzelsPerGlass = pretzelCount/(double)beerCount;
System.out.prtintln(pretzelCount + “ pretzels.”);
System.out.prtintln(beerCount + “ glasses of beer.”);
System.out.prtintln(“You have “ + pretzelsPerGlass
+ “ pretzels for each glass of beer.”);
}
}
©Duane Szafron 1999
9
GotBeer with Exceptions
(1 of 2)
Public class GotBeer
{ public static void main(String[ ] args)
{ int beerCount, pretzelCount;
double pretzelsPerGlass;
try {
System.out.println(“Enter number of pretzels:”);
pretzelCount = Savit.readLineInt( );
System.out.println(“Enter number of glasses of beer:”);
beerCount = Savit.readLineInt( );
if (beerCount <= 0)
throw new Exception(“No Beer!);
©Duane Szafron 1999
10
GotBeer with Exceptions
(1 of 2)
pretzelsPerGlass = pretzelCount/(double)beerCount;
System.out.prtintln(pretzelCount + “ pretzels.”);
System.out.prtintln(beerCount + “ glasses of beer.”);
System.out.prtintln(“You have “ + pretzelsPerGlass
+ “ pretzels for each glass of beer.”);
} // End of “try” block.
Catch(Exception e)
{
System.out.println(e.getMessage()); //”No Beer!”
System.out.println(“Go to RAT’s”);
System.out.println(“Program Aborted”);
System.exit(0);
}
} } //End of “main”
©Duane Szafron 1999
11
Generic Exceptions in Java

In Java, the generic concept of an exception is
represented by a class called Throwable.

In Java, a throw statement is used to signal an unusual
situation in a program.

The Java syntax is:
throw <instance of a subclass of the Throwable class>

In Java, there are two subclasses of the Throwable class,
Error and Exception.

However, Java errors and exceptions are both considered
exceptions in the generic sense.
©Duane Szafron 1999
12
The throws Statement

A throws statement is used to signal that an
generic exception (Java exception or Java error)
has occurred.

The syntax of a throws statement is:
throws <throwable expression>

The <throwable expression> is any expression
that evaluates to an object that is an instance of
the Throwable class or any subclass.
©Duane Szafron 1999
13
Throwing an Error

An Error is used when the program should be halted.

For example, we could modify our Ratio constructor:
public Ratio(int top, int bottom) {
/* pre: bottom != 0
post: constructs a ratio equivalent to top/bottom */
// Assert.pre(bottom != 0, "Denominator must not be 0");
if (bottom == 0)
throw new Error(“Denominator must not be 0”);
this.numerator = top;
this.denominator = bottom;
}
©Duane Szafron 1999
code based on Bailey pg. 8
14
An Error Halts the Program

When an error is thrown, the program is halted, a
message is displayed, and the stack frames are displayed:
application
_exceptionOccurred: java.lang.Error (Denominator must not
be 0)
java.lang.Error: Denominator must not be 0
at Ratio.<init>(Ratio.java)
at RatioTest.main(RatioTest.java)
at
com.apple.mrj.JManager.JMStaticMethodDispatcher.run(JM
AWTContextImpl.java)
at java.lang.Thread.run(Thread.java)
detailed
©Duane Szafron 1999
15
Exceptions

An Exception is used when some special code
may be used to handle the exception.

Every method that throws an exception must
either catch (handle) the exception or pass the
exception back to calling method using a throws
clause in its method signature.

When an exception is thrown, the java interpreter
looks for an exception handler.
©Duane Szafron 1999
16
Throwing an Exception

For example:
public Ratio(int top, int bottom) throws Exception {
/* pre: bottom != 0
post: constructs a ratio equivalent to top/bottom */
if (bottom == 0)
throw new Exception("Denominator must not be 0");
this.numerator = top;
this.denominator = bottom;
}
©Duane Szafron 1999
code based on Bailey pg. 8
17
The throws Clause

Each using method of the method that throws an
exception must also either catch the exception or have a
throws clause in its signature to throw it to its caller:
public Ratio add(Ratio other) throws Exception {
/* pre: other is non-null
post: return new fraction - the sum of this and
other */
Assert.pre(other != null, "Other must not be null");
return new Ratio (this.numerator*other.denominator+
this.denominator*other.numerator,
this.denominator*other.denominator);
}
code based on Bailey pg. 8
©Duane Szafron 1999
18
Chaining throws clauses

Eventually either the Exception must be caught or the
signature of the main method must contain a throws
clause:
public static void main(String args[]) throws Exception{
Ratio r = new Ratio(1,1);
r = new Ratio(1,2);
r.add(new Ratio(1,3));
r = r.add(new Ratio(1,4));
System.out.println(r.value());
r = new Ratio(1, 0);
// r == 1.0
// r == 0.5
// r still 0.5
// r == 0.75
// 0.75 printed
// should be an exception
}
©Duane Szafron 1999
code based on Bailey pg. 9
19
Exceptions not Caught

If an exception is not caught by any handler, the exception
behaves like an Error: the program is halted, a message is
displayed, and the stack frames are displayed:
_exceptionOccurred: java.lang.Exception (Denominator must not
be 0)
java.lang.Exception: Denominator must not be 0
at Ratio.<init>(Ratio.java)
at RatioTest.main(RatioTest.java)
at
com.apple.mrj.JManager.JMStaticMethodDispatcher.run(JMAWT
ContextImpl.java)
at java.lang.Thread.run(Thread.java)
©Duane Szafron 1999
20
The try-catch-finally statement

A try-catch-finally statement is used to catch an
exception (and therefore to prevent program
termination).

The EBNF Java syntax is:
try <try block> {<catch clause>} [<finally clause>];
Recall that in Extended BNF, { } means zero or more
occurrences and that [ ] means an optional
occurrence.

The <try block> is just a compound statement.
©Duane Szafron 1999
21
The catch clause

The Java syntax for a catch clause is:
catch (<exception declaration>) <catch block>

The <catch block> is just a compound
statement.

The <exception declaration> declares the
classes of exception that will be caught.
Its syntax is:
<exception classname> <variable>
©Duane Szafron 1999
Simple Example Syntax
22
enhanced

Here is the syntax for a simple example with one
catch clause and no finally clause:
1: If y=0 & if no catch clause, Exit
r = new Ratio(x, y); y = 0
3
2
y ~= 0
/* . . . more statements . . . */
See slide16
}
for where
catch (Exception anException) {
throws
System.out.println(anException);
takes place
r = new Ratio();
// initializes to 0/1
}
try {
©Duane Szafron 1999
code based on Bailey pg. 9
23
Semantics for Simple try-catch 1

If an expression in the try block of a
statement with one catch clause and no
finally clause throws an exception:
– the rest of the code in the try block is skipped.
– If the exception “matches” the catch clause, the
statements in the catch block are run, followed by
the rest of the method (case 3).
– If the exception does not match the catch clause,
the rest of code in the method is skipped and the
exception is thrown to the calling method (case 1).
©Duane Szafron 1999
24
Semantics for Simple try-catch 2

If an expression in the try block does not
throw an exception (case 2):
– The catch clause is skipped.
– The rest of the method is run normally.

If you put a try-catch-finally statement around
a method that may generate an exception,
you can remove the throws clause in the
calling method’s signature.(Why? ...
because you are handling the exception in the method with
the Catch phrase.)
©Duane Szafron 1999
25
Example: try-catch

For example:
public static void main(String args[ ]) throws Exception {
Ratio r;
try {
r = new Ratio(1, 0);
}
catch (Exception anException) {
System.out.println(anException);
r = new Ratio(); // initializes to 0/1
Denominator must not be 0
} java.lang.Exception:
0.0
System.out.println(r);
(Note ... See slide 10)
}
©Duane Szafron 1999
code based on Bailey pg. 9
26
Why Use Exceptions?

Why not just put the exception code in the method
where the exception is thrown instead of throwing the
exception?

Because, different callers may want to handle the
same exception differently.

For example, the previous segment binds the variable
“r” to a “zero” Ratio.

A different segment might want to bind the variable “r”
to null if an exception occurs.
©Duane Szafron 1999
27
Exception Matching

When does a thrown exception “match” a catch clause?
– The thrown exception has a class.
– The variable in the exception declaration of the catch
clause has a declared class.
– They “match” if class of the thrown exception is the
same as the declared class in the catch clause or is
one of its subclasses.
©Duane Szafron 1999
28
Example: Exception Matching 1

For example if the thrown exception class is a
NumberFormatException:
public Ratio(int top, int bottom) throws
NumberFormatException{
/* pre: bottom != 0
post: constructs a ratio equivalent to top/bottom */
if (bottom == 0)
throw new NumberFormatException(
"Denominator must not be 0");
this.numerator = top;
this.denominator
= bottom;
It can
be caught by a NumberFormatException
or any of its
}
superclasses:
©Duane Szafron 1999
code based on Bailey pg. 8
29
Example: Exception Matching 2
public static void main(String args[ ]) {
Ratio r;
try {
r = new Ratio(1, 0);
}
catch (NumberFormatException anException) {
// or IllegalArgumentException or RuntimeException or
// Exception
System.out.println(anException);
r = new Ratio(); // initializes
to 0/1
java.lang.NumberFormatException:
Denominator
must not be 0
0.0
}
System.out.println(r);
}
©Duane Szafron 1999
code based on Bailey pg. 8
30
Throwable Inheritance Hierarchy
Object
Throwable
Error
Linkage
Exception
ClassNotFound
IllegalArgument
IllegalThreadState
Runtime
IndexOutOfBound
NumberFormat
User-Defined?
©Duane Szafron 1999
31
User-defined Throwable Classes

You can define your own Exception subclasses.

This allows you to conditionally match only the
Exceptions that you want to match.

You can also define your own Error subclasses,
although you cannot use them to “catch” errors.
©Duane Szafron 1999
32
Example: User-defined Errors 1

For example, the implementation of the Assert
class, uses a new error subclass:
static public void pre(boolean test, String message)
// pre: result of precondition test.
// post: does nothing if test true, otherwise abort w/message
{
if (test == false) throw new FailedPrecondition(message);
}
©Duane Szafron 1999
code from Bailey structure package
33
Example: User-defined Errors 2
class FailedAssertion extends Error {
public FailedAssertion(String reason)
// post: constructs a new failed assertion error
{
Error
super("\nAssertion that failed: " + reason);
subclass of
} }
Failed Assertion
class FailedPrecondition extends FailedAssertion {subclass of
public FailedPrecondition(String reason)
Failed Precondition
// post: constructs a new failed precondition
{
super("\nA precondition: " + reason);
overrides
} }
©Duane Szafron 1999
code from Bailey structure package
34
“finally” and Multiple catches

You can put multiple catch clauses in the try
statement to handle different kinds of exceptions in
different ways.

If you want to execute some code, whether an
exception was raised or not, you can use the optional
finally clause.

The syntax of a finally clause is: finally <finallyBlock>

The <finallyBlock> is just a compound statement.
©Duane Szafron 1999
35
Full Semantics of try-catch-finally 1

If an expression in the try block throws an
exception:
– the rest of the code in the try block is
skipped.
– If the exception “matches” the first catch
clause
•
•
•
•
the code in its catch block is run
the optional code in the finally clause is run.
the rest of the catch clauses are ignored.
the rest of the code in the method is run.
©Duane Szafron 1999
36
Full Semantics of try-catch-finally 2
– If the exception does not “match” the first
catch clause, similar actions are taken for the
first “matching” catch clause.
– If the exception does not “match” any catch
clause
• the optional code in the finally clause is run
• all other code in the method is abandoned
• the exception is thrown to the calling method.
©Duane Szafron 1999
37
Example: finally & Multiple catches 1
public Ratio divide(Ratio other) throws Exception {
/* pre: other is non-null
pre: other is not zero
post: return new fraction - the division of this and other
*/
if (other == null)
throw new NullPointerException();
else if (other.numerator == 0)
throw new ArithmeticException();
else
return new Ratio(this.numerator*other.denominator,
this.denominator*other.numerator);
}
}
©Duane Szafron 1999
code based on Bailey pg. 9
38
Example: finally & Multiple catches 2
public static void main(String args[ ]) {
try {
UseRatio.divide(new Ratio(1, 2), new Ratio(3,4));
// should work
UseRatio.divide(new Ratio(1, 2), new Ratio(0,4));
// ArithmeticException caught in UseDivide()
UseRatio.divide(new Ratio(1, 2), null);
// NullPointerException caught in UseDivide()
UseRatio.divide(null, new Ratio(3,4));
// NumberFormatException NOT caught in UseDivide()
}
catch (Exception anException) {
System.out.println("NumberFormatException not caught by
divide()");
} }
code based on Bailey pg. 9
©Duane Szafron 1999
39
Example: finally & Multiple catches 3
private static void divide(Ratio top, Ratio bottom) throws
Exception
/* Compute the division of top by bottom and report the answer. If
top is null then change it to an invalid ratio 1/0 to generate a
NumberFormatException that won't be caught. Catch the other
exceptions: bottom is zero or bottom is null. */
Ratio answer;
answer = null;
try {
if (top == null)
top = new Ratio(1, 0); //Doesn’t make sense but throws
// NumberFormat Exception
answer = top.divide(bottom); }
code based on Bailey pg. 9
©Duane Szafron 1999
40
Example: finally & Multiple catches 4
catch (ArithmeticException anException) {
System.out.println("Arithmetic Except: no div by 0");
answer = new Ratio(); }
catch (NullPointerException anException) {
System.out.println("NullPointerExcept: no div by null");
answer = new Ratio(); }
finally {
System.out.println("Finally the answer: " + answer); }
// rest skipped for NumberFormat Exception since not caught
System.out.println("End method answer: ” + answer.value());
}
©Duane Szafron 1999
code based on Bailey pg. 9