Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Exception Handling (Chapter 8) CS 180 Recitation - February 29, 2008 Department of Computer Science Purdue University Announcements • • • Projects are examined by software that detects potential cheating Project 4 handed back Project 4 test cases are posted. Before regrade request, test your program with them. For regrade, contact with Jalaja Padma Introduction • • • Exceptions are cases that change a program’s normal flow of control. Every program should handle possible exceptions. Assuming nothing will go wrong through out the program execution is wrong. After all; anything that can go wrong, will go wrong. Introduction • • To handle exceptions, Java’s exception handling facilities should be used. 2 sections of a program: • Code segments that handle normal flow of control. • Code segments that handle the exceptional cases that might occur through out the execution. Test Class Consider this simple program: import java.util.InputMismatchException; import java.util.Scanner; public class Test { public static void main(String[] args) { Scanner keyboard = new Scanner(System.in); System.out.println("Please enter the number of eggs:"); int numberOfEggs = keyboard.nextInt(); System.out.println(numberOfEggs); } } Test Class • Problem: What if the user types “4” instead of 4. Please enter the number of eggs: “4” Exception in thread "main" java.util.InputMismatchException at java.util.Scanner.throwFor(Unknown Source) at java.util.Scanner.next(Unknown Source) at java.util.Scanner.nextInt(Unknown Source) at java.util.Scanner.nextInt(Unknown Source) at Test.main(Test.java:11) • Unacceptable if the user doesn’t know Java Test Class (Right Way) import java.util.Scanner; public class Test { public static int DEFAULT_EGGS = 5; public static void main(String[] args) { Scanner keyboard = new Scanner(System.in); System.out.println("Please enter the number of eggs:"); int numberOfEggs; try{ numberOfEggs = keyboard.nextInt(); } catch(Exception e){ numberOfEggs = DEFAULT_EGGS; System.out.println("Bad input!!!\nSetting the default value, " + numberOfEggs); } System.out.println(numberOfEggs); } } Test Class (Handling multiple exceptions) import java.util.Scanner; public class Test { public static int DEFAULT_EGGS = 5; public static void main(String[] args) { Scanner keyboard = new Scanner(System.in); System.out.println("Please enter the number of eggs:"); int numberOfEggs = 0; int numberOfBasket = 0; int eggsPerBasket = 0; try{ numberOfEggs = keyboard.nextInt(); System.out.println("Please enter the number of baskets:"); numberOfBasket = keyboard.nextInt(); eggsPerBasket = numberOfEggs/numberOfBasket; } catch(Exception e){ //Opps, now what to catch? Bad user input or division by zero? } System.out.println(numberOfEggs); } } Test Class (Handling multiple exceptions) import java.util.InputMismatchException; import java.util.Scanner; public class Test { ……………. ……………. try{ numberOfEggs = keyboard.nextInt(); System.out.println("Please enter the number of baskets:"); numberOfBasket = keyboard.nextInt(); eggsPerBasket = numberOfEggs/numberOfBasket; } catch(InputMismatchException e){ numberOfEggs = DEFAULT_EGGS; System.out.println("Bad input!!!\nSetting the default value, " + numberOfEggs); } catch(ArithmeticException e){ System.out.println(“Division by zero”); numberOfBasket = 1; eggsPerBasket = numberOfEggs; } System.out.println(numberOfEggs); } } Handling multiple exceptions • • • Although it catches multiple exceptions, this piece of code doesn’t execute all the statements if an exception occurs at the first line of try block. If there is a way to handle exception without a try-catch block, use it. (i.e. instead of using ArithmeticException an if statement that checks if numberOfBasket<1 would suffice) For each statement, form a different try-catch block and catch every possible exception. Handling multiple exceptions • While catching exceptions, it is crucial that order goes from specific exception (sub-class) to general exception (parent class) since the first matching catch is executed. Compile Error Scanner keyboard = new Scanner(System.in); try{ int tmp = 10/keyboard.nextInt() - keyboard.nextInt(); } catch (Exception e){ Parent Class e.printStackTrace(); } catch (InputMismatchException e){ Sub-class of Exception System.out.println(e.getMessage()); } The flow of control will never go into the last catch block since all of the exception will be caught by the first catch block. This will cause a compile error. So, these 2 catch blocks should be swapped. Accounting for Exceptions • • • An exception can be caught in a catch block within a method definition. Alternatively, the possibility of an exception can be declared at the start of the method definition by placing the exception-class name in a throws clause. These two approaches can be mixed in a method, catching some exceptions and declaring others in a throws clause. Accounting for Exceptions (1st option) • Catching an exception inside of a method import java.util.InputMismatchException; import java.util.Scanner; public class Test { public static void main(String[] args) { int numberOfEggs = getInput("Please enter the number of eggs:", 1); int numberOfBasket = getInput("Please enter the number of baskets:", 1); if (numberOfBasket < 1) numberOfBasket = 1; int eggsPerBasket = numberOfEggs/numberOfBasket; System.out.println(numberOfEggs+"-"+numberOfBasket+"-"+eggsPerBasket); } public static int getInput(String prompt, int numOfTry){ Scanner keyboard = new Scanner(System.in); System.out.println(prompt); int k = 0; try{ k = keyboard.nextInt(); } catch(InputMismatchException e){ System.out.println("Bad input!!!(try number: "+numOfTry+")"); k = getInput(prompt, numOfTry+1); } return k; } } Accounting for Exceptions (2nd option) • Catching an exception where the method is called public static void main(String[] args) { int numberOfEggs = 0; try{ numberOfEggs = getInput("Please enter the number of eggs:"); } catch (InputMismatchException e){ numberOfEggs = 5; } int numberOfBasket = 0; try{ numberOfBasket = getInput("Please enter the number of baskets:"); }catch (InputMismatchException e){ numberOfEggs = -1; numberOfBasket = -1; } … } public static int getInput(String prompt) throws InputMismatchException{ Scanner keyboard = new Scanner(System.in); System.out.println(prompt); int k = keyboard.nextInt(); return k; } Accounting for Exceptions • • Some method in the calling hierarchy should handle the exception (i.e. either getInput or main method). If an exception is thrown, but never caught, either the program terminates or its behavior becomes unreliable. Keep It Simple • • If the way the exception is handled depends on the calling method, let the calling method handle the exception (i.e. 2nd option, in the second try-catch the first variable is changed used in the first trycatch). 1st option is more specific and is less likely to be used through out the program, so it is a good practice to implement 2nd option. Implementing New Exception Classes • • • Don’t forget catch handlers won’t be part of user-defined exception classes In other words you should explicitly indicate in your program when to throw your own exception Test class example continued: Test Class (Cont.) import java.util.InputMismatchException; import java.util.Scanner; public class Test { public static void main(String[] args) { int numberOfEggs = getInput("Please enter the number of eggs:", 1); int numberOfBasket = getInput("Please enter the number of baskets:", 1); try{ if (numberOfBasket < 1) throw new DivideByZeroException(); } catch (DivideByZeroException e) { System.out.println(e.getMessage()); numberOfBasket = 1; } int eggsPerBasket = numberOfEggs/numberOfBasket; System.out.println(numberOfEggs+"-"+numberOfBasket+"-"+eggsPerBasket); } public static int getInput(String prompt, int numOfTry){…} } class DivideByZeroException extends Exception { public DivideByZeroException() { super("Dividing by Zero!"); } public DivideByZeroException(String message) { super(message); } } throws Clause Not Allowed in actionPerformed • • • A throws clause cannot be added to method actionPerformed in any action listener class. Any exception thrown in method actionPerformed must be caught in method actionPerformed. Similarly, if method windowClosing is redefined in a window listener class, you may not add a throws clause to method windowClosing. Quiz Scanner keyboard = new Scanner(System.in); int tmp = 0; try{ tmp = 10/keyboard.nextInt() - keyboard.nextInt(); } catch (InputMismatchException e){ System.out.println(“InputMismatchException”); tmp = -1 } catch (Exception e){ System.out.println(“Exception”); tmp = -2; } Assume a user tries to enter 0 first, then 5. What is the value of tmp at the end?