ExceptionsHandling the unexpected
Motivation • So far, most of our code has been somewhat näive • We have assumed that nothing goes wrong… • User enters correct input • We never address outside the boundaries of an array • …and so on DCS – SWC
Motivation • Of course, the real world works differently public class BankAccount { public void withdraw(double amount) { if (amount > balance) // Now what? } ... } DCS – SWC
Motivation • Possible actions depend on our interpre-tation of this situation • Legal – just do business logic • Illegal, and we know what to do – perhaps just do nothing • Illegal, and we do not know what to do! • Error detection and error handling are often separated in code! DCS – SWC
Motivation • Problem: Can become very complex to ”drag” error handling code around in code for business logic • Error-handling may be application-specific • GUI-application: Pop-up window • Other: Write to a log file • Business logic code should not choose strategy for error handling! DCS – SWC
Motivation • Next problem: Error handling code is often very ”far away” from error detction askUser doAction makeWithdraw withdraw main ? Error detected Error handling DCS – SWC
Motivation • Management of errors can be broken down into several tasks: • Detection – realising an error situation has occurred • Signaling – making the surrounding code aware that an error has been detected • Capturing – taking responsibility for handling the error • Handling – performing the error handling actions DCS – SWC
Exceptions • The mechanism for crossing the gap of method calls is exceptions • An exception in itself is ”just another class” • We can create exception objects just as we can create other objects • An exception object contains information about the type of error which occurred • Java contains several built-in exception classes, forming an inheritance hierarchy DCS – SWC
Throwing and catching • Exception can be thrown and catched • What does that mean!? • A very different flow than usual method calls • An exception is thrown up through the chain of method calls DCS – SWC
Throwing and catching askUser doAction makeWithdraw withdraw main Who will catch the exception? Error detected – throw! DCS – SWC
Throwing and catching • A throw can look like this in Java: public void withdraw(double amount) { if (amount > balance) { IllegalArgumentException ex = new IllegalArgumentException(”...”); throw ex; } balance = balance – amount; } NOTE! DCS – SWC
Throwing and catching • An exception is now thrown; this changes the flow of code immediately! • Remaining code in the method throwing the exception is not executed • Somebody must catch the exception • In order to catch the exception, we must write an exception handler DCS – SWC
Throwing and catching • General exception handler structure: try { // Code which may throw an exception ... } catch (ExceptionType ex) { // Proper handling of exception ... } DCS – SWC
Throwing and catching try { myAccount.withdraw(1000); myAccount.getTransactions(); ... } catch (IllegalArgumentException ex) { System.out.println(ex.getMessage()); ex.printStackTrace(); } DCS – SWC
Throwing and catching • Things to note: • Error detection (throw) and error handling (try/catch) is usually not in the same method • The catch statement only catches exceptions of the specified type • Information about the error is found implicitly – by the type of the exception – and explicitly from e.g the text stored in the object DCS – SWC
Throwing and catching • Throw early, catch late! • If you cannot fix a pro-blem correctly, throw an exception • Only catch an exception if you really know how to fix the problem DCS – SWC
Throwing and catching try { myAccount.withdraw(1000); myAccount.getTransactions(); ... } catch (Exception ex) { // do nothing... } Tempting, but bad…! DCS – SWC
Checked and Unchecked • How do I know what exceptions some piece of code can throw…? • Difficult to code a method correctly without this knowledge • Two types of exceptions exist • Checked exception • Unchecked exception DCS – SWC
Checked and Unchecked • Checked exception • Used for problems beyond the control of the programmer • Corrupted file, network problems, etc.. • Compiler insists that you explicitly decide what to do about it • Option 1: Re-throw the exception • Option 2: Handle the exception, using a catch clause matching the exception DCS – SWC
Checked and Unchecked // Suppose draw() can throw DrawException draw(Figure f); // Compiler will not like this! public void drawOne(Figure f) { getScreen().draw(f); } DCS – SWC
Checked and Unchecked // Option 1: Re-throw the exception // (i.e. do nothing…) public void drawOne(Figure f) throws DrawException { getScreen().draw(f); } DCS – SWC
Checked and Unchecked // Option 2: Handle the exception public void drawOne(Figure f) { try { getScreen().draw(f); } catch (DrawException de) { // Code for handling the problem } } DCS – SWC
drawOne draw Option 1: drawOne does nothing, so it must annonce that it will (re)throw the exception draw drawOne Option 2: drawOne handles the exception, so it is ”consumed” by drawOne Checked and Unchecked DCS – SWC
Checked and Unchecked • Unchecked exception • Used for problems which the programmer should be able to prevent • Null reference, out of bounds reference,… • Why do we have these…? Accidents do happen…! • Unchecked exceptions are not announced DCS – SWC
The finally Clause • Sometimes we need to execute some specific code after an exception occurs • Typically ”clean-up” code – close a file connection, a database connection, etc. • Where do we put this code…? • In exception handlers? Difficult, who actually catches the exception… • In a finally clause! DCS – SWC
The finally Clause PrintWriter out = new PrintWriter(filename); ... try { writeData(out); } finally { // This code will always be executed, // even if the above code throws an exception out.close(); } DCS – SWC
The finally Clause • The code in the finally clause is guaran-teed to be executed, in one of these ways: • If no exceptions are thrown: After completing the last statement in the try block • If an exception is thrown: • Execute code in finally clause • Exit to exception handler DCS – SWC
The finally Clause try { try { } finally { } } catch { } try { } catch { } finally { } NOT SO GOOD GOOD DCS – SWC
Making your own exceptions • Throw exceptions that are as specific as possible – also in terms of type • Many built-in exceptions to choose from • Can be appropriate to create your own exceptions • Just extend existing class DCS – SWC
Making your own exceptions public class InsufficientFundsException extends RunTimeException { public InsufficientFundsException() {} public InsufficientFundsException(String message) { super(message); } } DCS – SWC
Exceptions vs. Flow control • Exceptions change the linear flow of code, just like if, while, etc. • However, they are only intended for error detection and handling • Do not use exceptions as a substitute for ordinary flow control DCS – SWC
Exceptions vs. Flow control GOOD for (int i = 0; i < noOfElements; i++) myArray[i] = i; try { for (int i = 0; /* No Test?? */ ; i++) myArray[i] = i; } catch (ArrayIndexOutOfBoundsException e) {} BAD DCS – SWC
Exceptions summary • Throw early, catch late • Only catch, if you can handle the problem correctly • You must deal with checked exceptions • Use try, catch and finally appropriately • Make your own exception classes, if you really need them • Exceptions are not for flow control DCS – SWC