C1: Exception Handling
CPSC 210
Learning Goals
- To determine whether or not a method’s specification is robust
- To design robust method specifications using exception handling
- To determine the flow-of-control when a method throws an exception
Why Exceptions?
// REQUIRES: numItems > 0
// MODIFIES: this
// EFFECTS: adds numItems to quantity of
// items purchased on this line item
public void addQuantity(int numItems) {
this.quantity += numItems;
}
Let's break this!!
lineItem.addQuantity(-1);
What do we want instead?
My Dear Caller - I see you passed in a
negative number to our addQuantity method.
This is not supported. We kindly ask you to
enter a positive number.
Method is not robust:
REQUIRES clause excludes values
Why Exceptions? (2)
- Especially for public methods, we usually cannot rely on values adhering to what we require!
- We need to be prepared for exceptional cases!
// MODIFIES: this
// EFFECTS: adds numItems to quantity of
// items purchased on this line item
// IF numItems < 1
// throws IllegalNumberException
public void addQuantity(int numItems)
throws IllegalNumberException {
if (numItems < 1) {
throw new IllegalNumberException();
}
this.quantity += numItems;
}
Method is robust: specifies behaviour for ALL inputs
Exceptions
public class IllegalNumberException extends Exception {
}
- Exceptions are thrown when a problem occurs
-
Exception class is part of the Java library
- Any exception is an instance of that class or a subclass
- The caller will have the choice to:
- catch the exception and address the problem
- propagate (= throw) the exception further to its caller
Exceptions (2)
-
There are two kinds of exceptions:
- checked
- unchecked
- Today we focus only on checked exceptions (don’t worry about the difference for now)
Call Stack & Throwing Exceptions
catch?
catch?
catch?
LineItem
addQuantity
GroceryBill
addPurchase
GroceryApp
main
Catching Exceptions
catch?
catch?
public void addPurchase(GroceryItem item, int quantity) {
// ...
try {
entry.addQuantity(quantity);
} catch (IllegalNumberException e) {
System.err.println("Quantity could not be added: " + quantity);
}
// ...
}
LineItem
addQuantity
GroceryBill
addPurchase
GroceryApp
main
The Finally Keyword
- Sometimes we want to execute code no matter if there was an exception caught or not
public void addPurchase(GroceryItem item, int quantity) {
// ...
try {
entry.addQuantity(quantity);
} catch (IllegalNumberException e) {
System.err.println("Quantity could not be added: " + quantity);
} finally {
System.out.println("Your quantity might have been added. Not sure.");
}
// ...
}
The Finally Keyword (2)
- A more real-life example
public void writeStringToFile(String string) {
FileWriter fw = new FileWriter("OutputFile.txt")
PrintWriter pw = new PrintWriter(fw);
try {
pw.println(string);
} catch (IOException e) {
System.out.println("Could not write to file");
} finally {
pw.close();
}
}
- We want to close our PrintWriter object no matter if the write process was successful or not
Lecture Ticket Review
Extra: Git Branching
Branch: main
Branch: mybranch
Create
Branch
Merge
Branch
Commits
Lecture Ticket
Lecture Lab
C1: Exception Handling
The End - Thank You!
Extra Slides...
a try/catch/finally statement...
- normally: executes its try block and then finishes normally
- must have at least one clause besides try (a catch or finally)
- may have any number of catches and up to one finally
- at the end of its normal execution, continues to the next statement (like almost any statement except throw/return)
-
catches exceptions under some circumstances:
-
if its try block ends abnormally with an exception object e
- and it has a catch block like: catch (ExcType e2)
- where e is a subtype of ExcType
-
then it finds the first such block
- and makes e the value of e2
- and executes that catch block
- and then finishes the whole try/catch normally
-
if its try block ends abnormally with an exception object e
- just before the ending execution (normally or abnormally) executes its finally block (if any) and then resumes ending execution
Throwing Multiple Exceptions
public void addPurchase(GroceryItem item, int quantity)
throws CouldNotAddPurchaseException {
// ...
try {
entry.addQuantity(quantity);
} catch (IllegalNumberException e) {
System.err.println("Quantity could not be added: " + quantity);
throw new CouldNotAddPurchaseException();
} // POSSIBLY MORE CATCH CLAUSES TO CATCH OTHER EXCEPTIONS
// ...
}
- We can catch one exception and throw another...
- ...this way, different methods in the call stack can treat errors in their own way...
GroceryBill bill = new GroceryBill();
try {
bill.addPurchase(milk, 2);
} catch (CouldNotAddPurchaseException e) {
System.err.println("At least one purchase could not be added");
}
CPSC210 - C1 Exception Handling
By Steven Wolfman
CPSC210 - C1 Exception Handling
- 237