COMP-202 Exceptions
Lecture Outline Exceptions Exception Handling The try-catch statement The try-catch-finally statement Exception propagation Checked Exceptions 2
Exceptions An exception is an object that describes an unusual or erroneous situation that prevents normal program execution from continuing An exception typically requires some action before execution can continue. This activity is called handling an exception. Example exceptions: Division by zero Reading the wrong data type from a Scanner Accessing a non existing array-element Accessing a property of a null object Trying to write to a file that is stored on a CD-ROM 3
Using Exceptions When such an unusual situation occurs The program interrupts normal execution An exception is automatically instantiated and thrown If nothing is done, the program terminates Instead of letting the program terminate, an exception can be caught and handled by another part of the program The programmer writes special code, called a handler, that is executed whenever an exception is thrown A program can therefore be separated into a normal execution flow and an exception execution flow 4
Exception Examples Example exceptions: java.lang.arrayindexoutofboundsexception java.lang.stringindexoutofboundsexception java.lang.nullpointerexception java.lang.arithmeticexception java.lang.outofmemoryerror java.lang.classformaterror java.lang.internalerror java.lang.virtualmachineerror An error usually represents a unrecoverable situation and should not be caught / handled Because it is usually very difficult to do anything useful 5
Ignoring an Exception If an exception is ignored by the program, the program will terminate and produce an appropriate message The message includes a call stack trace that indicates on which line the exception occurred The call stack trace also shows the method call trail that lead to the execution of the offending line 6
Zero.java public class Zero { // Deliberately divides by zero to produce an exception public static void main (String[] args) { int numerator = 10; int denominator = 0; System.out.println(numerator / denominator); System.out.println( Will this line be printed?"); ArithmeticException: / by zero at Zero.main(Zero.java:6) at sun.reflect.nativemethodaccessorimpl.invoke0(native Method) at sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:39) at sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:25) at java.lang.reflect.method.invoke(method.java:585) 7
The try Statement To handle an exception when it occurs, the line that throws the exception has to be executed within a try block A try block is followed by one or more catch clauses, which contain code that define the handlers Each catch clause has an associated exception type When an exception occurs, processing continues at the first catch clause that matches the exception type After the handling, execution continues at the first statement after the try-catch block 8
General format: Using try-catch try { // code which may throw an exception catch(exctypea ea) { // control goes here if an ExcTypeA occurs catch(exctypeb eb) { // control goes here if a ExcTypeB occurs... 9
ZeroException.java public class ZeroException { // Deliberately divides by zero to produce an exception public static void main (String[] args) { int numerator = 10; int denominator = 0; try { System.out.println(numerator / denominator); catch (ArithmeticException ex) { System.out.println( Arithmetic error: + ex.getmessage()); System.out.println( Will this line be printed?"); 10
The finally Clause A try statement can have an optional clause designated by the reserved word finally The statements in the finally clause are always executed before the try-catch block is left If no exception is encountered If an exception is encountered and handled If an exception is encountered and propagated (exception propagation is explained on slide 13) 11
Using try-catch-finally General format: try { // code which may throw an exception catch(exctypea ea) { // control goes here if an ExcTypeA occurs... { finally { // control goes here before leaving the block 12
Exception Propagation If it is not possible to handle the exception where it occurs, it can be handled at a higher level An exception propagates up through the method calling hierarchy An exception occurrence within a method that is not handled terminates the method. The exception propagates to the caller, i.e. it is thrown at the point where the method has been called This continues until the exception is caught and handled, or until it reaches the outermost level, in which case the program terminates abnormally A try block that contains a call to a method in which an exception is thrown can be used to catch that exception 13
Zero2.java public class Zero2 { public static void divide(int num, int den) { System.out.println(num / den); System.out.println( Will line A be printed?"); public static void main (String[] args) { int numerator = 10, denominator = 0; divide(numerator, denominator); System.out.println( Will line B be printed?"); ArithmeticException: / by zero at Zero2.divide(Zero2.java:3) at Zero2.main(Zero2.java:8) at sun.reflect.nativemethodaccessorimpl.invoke0(native Method) at sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:39) at sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:25) at java.lang.reflect.method.invoke(method.java:585) 14
Zero2Exception.java public class Zero2Exception { public static void divide(int num, int den) { System.out.println(num / den); System.out.println( Will line A be printed?"); public static void main (String[] args) { int numerator = 10; int denominator = 0; try { divide(numerator, denominator); catch (ArithmeticException ex) { System.out.println( Arithmetic error: + ex.getmessage()); System.out.println( Will line B be printed?"); 15
What to Do When an Exception Occurs? Ignore the exception The program terminates Handle the exception in the method m in which it occurs Do this if there is some way to continue to provide the functionality m (recovery) The exception handling code resides in the method m Handle the exception in a method p that directly (or indirectly) called m Do this if there is some way to continue to provide the functionality offered by p without the help of m (compensation) The exception handling code resides somewhere in the calling hierarchy of m 16
Checked Exceptions An exception is either checked or unchecked Unchecked exceptions Can (but do not need to) be caught or propagated but if not caught anywhere then program terminates A checked exception Must be caught within within a try-catch block within the method in which it occurs, or Must be declared to be propagated to the outer method, A throws clause must be appended to the header of the method The compiler will complain if a checked exception is not handled or declared appropriately 17
The Exception Class Hierarchy Checked Throwable Exception Error IOException... RuntimeException OutOfMemory... VirtualMachineError NullPointerException... ArithmeticException Unchecked 18
More on Exceptions It is possible to define your own exceptions to signal application-specific exceptional situations For example: BalanceTooLow exception, when a request is made to withdraw from an account an amount that is higher than the current balance WordNotFound exception, when a request is made to find the first occurrence of a word in a string 19
Declaring Your Own Exceptions To declare your own exception, you must subclass the Exception class Or the RuntimeException class, if you want your exception to be unchecked class NotEnoughFundsException extends Exception { No need to define fields or methods The exception class already provides two constructors: one without parameters and one that takes a string 20
Account with Exception public class Account { private double balance; Boolean return value not needed anymore! public double getbalance() { return balance; public void withdraw(double amount) throws NotEnoughFundsException { if (balance < amount) { throw new NotEnoughFundsException(); balance = balance - amount; 21
Class Client (1) (from OO part 2) public class Client { private String name; private Account checking; private Account savings; public Client(String clientname, double initialcheckingdeposit, double initialsavingsdeposit) { name = clientname; checkings = new Account(initialCheckingDeposit); savings = new Account(initialSavingsDeposit); (continues on next slide) 22
Class Client (2) (continued from previous slide) public double getbalancechecking() { return checking.getbalance(); public withdrawchecking(double amount) throws NotEnoughFundsException { checking.withdraw(amount); public void depositchecking(double amount) { checking.deposit(amount); Boolean return value not needed anymore! /* similar for getbalancesavings, withdrawsavings, and depositsavings */ 23
Class Client (3) (continued from previous slide) public transfer(accountkind from, double amount) throws NotEnoughFundsException { if (from == Checking) { checking.withdraw(amount)); savings.deposit(amount); else { savings.withdraw(amount)); checking.deposit(amount); Boolean return value not needed anymore! 24
Class Bank public class Bank { public static void main (String[] args) {! Client bob = new Client( Bob, 100, 0);! Client alice = new Client( Alice, 250, 0);! bob.depositchecking(100);! System.out.println( Bob s checking is now: + bob.getbalancechecking()); try { alice.withdrawsavings(20)); System.out.println( Withdraw successful ); catch (NotEnoughFundsException e) { System.out.println( Withdraw not successful ); 25
Abstraction Levels and Exceptions The following slides are meant to illustrate how exceptions and exception handling work in the context of functional decomposition / different levels of abstraction Example: Go to McGill in the morning I can get to McGill By roller blades By bicycle By bus/metro By car Walk 26
Roller Blades To use my roller blades, I need to do the following: public void gobyrollerblade() { checkweatherforecast(); leftshoe.inspect(); leftshoe.puton(); leftshoe.tielaces(); // same for right shoe helmet.puton(); myipod.play(); bladetomcgill(); But what if things go wrong? 27
Tying Laces What can go wrong when I tie the laces? Laces can rip So the method header for tielaces could be: public void tielaces() throws LacesRipped; What is the consequence for gobyrollerblade? 28
Roller Blades with Exceptions (1) public void gobyrollerblade() { checkweatherforecast(); leftshoe.puton(); try { leftshoe.tielaces(); catch (LacesRipped e) { leftshoe.replacelaces(); leftshoe.tielaces(); // same for right shoe helmet.puton(); myipod.play(); bladetomcgill(); What if more things can go wrong? 29
Roller Blades with Exceptions (2) public void gobyrollerblade() throws BladingImpossible { try { if (checkweatherforecast() == WeatherKind.Rain) { throw new CantBladeInBadWeather(); leftshoe.puton(); try { leftshoe.tielaces(); catch (LacesRipped e) { leftshoe.replacelaces(); leftshoe.tielaces(); // same for right shoe helmet.puton(); try { myipod.play(); catch (BatteryDead e) { // on purpose empty... // it s sad, but ok to blade // without music bladetomcgill(); catch (CantBladeInBadWeather e) { throw new BladingImpossible(); catch (LacesRipped e) { throw new BladingImpossible(); 30
GoToMcGill with Exception Handling public void gotomcgill() throws ImpossibleToReachToday { int favorite = 0; boolean done = false; while (!done) { try { switch (favorite) { case 0: gobyrollerblade(); break; case 1: gobybike(); break; case 2: gobypublictransport(); break; case 3: gobycar(); break; case 4: walk(); done = true; catch (Exception e) { favorite++; if (favorite > 4) { throw new ImpossibleToReachToday(); 31
GoToMcGill Example: Normal Processing Normal Functionality gotomcgill Choosing between different ways of getting to McGill gobyrollerblade Sequencing of actions to use the blades tielaces Specific 32
GoToMcGill: Exceptional Processing Exception Interface gotomcgill: ImpossibleToReachToday gobyrollerblade: BladingImpossible tielaces: LacesRipped Exception Handling: gotomcgill: handles BladingImpossible gobyrollerblade: handles LacesRipped, CantBladeInBadWeather, BatteryDead tielaces: none 33