1 / 51

Exceptions

Exceptions. Problems with error reporting so far Either ignored exceptions or terminated program on first error. Error handling and regular code mixed User interface and computation code mixed. Exception will be reported to the user. Argument Printer. package main;

curt
Download Presentation

Exceptions

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Exceptions • Problems with error reporting so far • Either ignored exceptions or terminated program on first error. • Error handling and regular code mixed • User interface and computation code mixed

  2. Exception will be reported to the user Argument Printer package main; public class AnArgPrinter{ public static void main(String args[]) { System.out.println(args[0]); } }

  3. Regular and error code mixed together Error check if (args.length == 0 ) { System.out.println("Did not specify the argument to be printed. Terminating program."); System.exit(-1); } else { System.out.println(args[0]); }

  4. Regular and error code separate Exception handler try { System.out.println(args[0]); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Did not specify the argument to be printed. Terminating program."); System.exit(-1); }

  5. Printing multiple arguments: main public static void main (String args[]) { echoLines(numberOfInputLines(args)); }

  6. UI mixed in computation method Arbitrary legal value returned, program not halted numberOfInputLines static int numberOfInputLines(String[] args) { try { return Integer.parseInt(args[0]); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Did not enter an argument.") return 0; } }

  7. Decision to halt without full context echoLines static void echoLines (int numberOfInputLines) { try { for (int inputNum = 0; inputNum < numberOfInputLines; inputNum++) System.out.println(inputStream.readLine()); } catch (IOException e) { System.out.println("Did not input " + numberOfInputLines + " input strings before input was closed. "); System.exit(-1); } }

  8. Moral: Separate error detection and handling • In this example • Let echoLines() and numberOfInputLines() not do the error handling. • All they do is error reporting • Main does error handling and associated UI

  9. Error code solution • Pass back error codes to main • Works for procedures as we can make it return value instead of void • Does not work for functions as error code may be legal return value • Integer function returning all possible integer values

  10. Global variable solution • Store error codes in common variables • Does not work when there are multiple calls to the same method • A call may overwrite value written by another call • Variable may accessed by other methods sharing its scope

  11. Exception propagation • Java lets exceptions be “returned instead of regular values. • These propagate through call chain until some method handles them

  12. Tells caller that passing it the exception Propagating echoLines staticvoid echoLines (int numberOfInputLines) throws IOException { for (int inputNum = 0; inputNum < numberOfInputLines; inputNum++) System.out.println(inputStream.readLine()); }

  13. Propagating numberOfInputLines staticint numberOfInputLines(String[] args) throws ArrayIndexOutOfBoundsException { return Integer.parseInt(args[0]); } }

  14. Has context IO exception not caught Handling in main publicstaticvoid main (String args[]) { try { echoLines(numberOfInputLines(args)); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Did not enter an argument. Assuming a single input line.”); echoLines(1); } catch (IOException e) { System.out.println("Did not input the correct number of input strings before input was closed. "); } }

  15. Must be different names Handling in main publicstaticvoid main (String args[]) { try { echoLines(numberOfInputLines(args)); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Did not enter an argument. Assuming a single input line.”); try { echoLines(1); } catch (IOException ioe) { System.out.println("Did not input the one input string, which is the default in case of missing argument, before input was closed. "); } } catch (IOException e) { System.out.println("Did not input the correct number of input strings before input was closed. "); } }

  16. Bad idea as interpreter’s messages may be meaningless to the user Passing the buck in main public static void main (String args[]) throws IOException, ArrayIndexOutOfBoundsException { echoLines(numberOfInputLines(args)); }

  17. Java complains IOException neither handled nor declared Omitting IOException in throws clause static void echoLines (int numberOfInputLines) { for (int inputNum = 0; inputNum < numberOfInputLines; inputNum++) System.out.println(inputStream.readLine()); } Caller does not know what it must handle

  18. Omitting ArrayIndexOutOfBoundsException in throws clause static int numberOfInputLines(String[] args) { return Integer.parseInt(args[0]); } } No complaints from Java

  19. Java has two kinds of exceptions • Unchecked exceptions • Called “runtime”, but all exceptions are runtime! • Subclasses of RunTimeException • E.g. ArrayIndexOutofBoundsException • Uncaught exceptions need not be declared • Checked exceptions • Uncaught exceptions must be declared • Rationale for division?

  20. static void safeArrayIndexer throws ArrayIndexOutOfBoundsException () { String args[] = {“hello”, “goodbye”}; System.out.println(args[1]); } Array index does not imply exception Java cannot tell the difference Array index out of bounds guaranteed to not happen Misleading header

  21. Reasons for exceptions • User error • Programmer cannot prevent it • Should be acked • Analogous to specifying class methods in interface – a form of comments checked by Java • Internal error • Programmer can prevent • A method that can be erroneous probably is not really erroneous • Acking is probably misleading

  22. Justification of Java Rules Java rules justified if: • Checked (Non-runtime) exceptions = user errors • Unchecked (runtime) exceptions = internal errors

  23. Checked vs. Unchecked • Unchecked • No rules • Checked • uncaught in method body => acknowledged in method header • unacknowledged in method header => caught in method body (from 1) • unacknowledged in interface method-header => unacknowledged in class method-header • unacknowledged in interface method-header => caught in method body (from 2 and 3) • Interface can be used to force method implementations to catch exceptions

  24. Interface/Class relationship public interface StringEnumeration { ... public String nextElement(); } public class AnInputStreamScanner implements StringEnumeration { ... public String nextElement() { try { return inputStream.readLine(); } catch (IOException e) { return “”; } } } unacknowledged in interface method-header => caught in method body

  25. Interface/Class relationship public interface StringEnumeration { ... public String nextElement(); } public class AnInputStreamScanner implements StringEnumeration { ... public String nextElement() throws IOException{ return inputStream.readLine(); } } unacknowledged in interface method-header => caught in method body

  26. Unchecked, as most users will call hasMoreElements before nextElement() Interface/Class relationship public interface StringEnumeration { ... public String nextElement(); } public class AnInputStreamScanner implements StringEnumeration { ... public String nextElement() throws java.util.NoSuchElementException { if (!hasMoreElements()) throw new java.util.NoSuchElementException(); return inputStream.readLine(); } }

  27. Good idea to throw this exception when no more elements Standard Enumeration interface package java.util; public interface Enumeration { ... public Object nextElement(); } public class AnInputStreamScanner implements java.util.Enumeration{ ... public Object nextElement() throws java.util.NoSuchElementException { if (!hasMoreElements()) throw new java.util.NoSuchElementException(); return inputStream.readLine(); } }

  28. When next element erroneous because of user error (e.g. scanning rules violated) When no more elements Throwing multiple exceptions public interface StringEnumeration { ... public String nextElement() throws java.io.IOException; } public class AnInputStreamScanner implements StringEnumeration { ... public String nextElement() throws java.util.NoSuchElementException, java.io.IOException { if (!hasMoreElements()) throw new java.util.NoSuchElementException(); return inputStream.readLine(); } }

  29. Printing debugging information catch (ArrayIndexOutOfBoundsException e) { System.out.println(e); } e.getMessage() catch (ArrayIndexOutOfBoundsException e) { e.printStackTrace(); } Stack when exception is thrown

  30. Stack that existed when exception was thrown Printing stack

  31. Justification of Java Rules Java rules justified if: • Checked (Non-runtime) exceptions = user errors • Unchecked (runtime) exceptions = internal errors

  32. Problems with Java rules Unchecked exceptions can be caused by user error staticint numberOfInputLines(String[] args) { return Integer.parseInt(args[0]); } }

  33. Approach 1: Voluntarily list exception staticint numberOfInputLines(String[] args) throws ArrayIndexOutOfBoundsException { return Integer.parseInt(args[0]); } } No way to force every caller that does not handle it to ack it.

  34. Exception object thrown explicitly message Approach 2: Convert to existing checked exception staticint numberOfInputLines(String[] args) throws IOException { try { return Integer.parseInt(args[0]); } catch (ArrayIndexOutOfBoundsException e) { thrownew IOException (“First argument missing”); }

  35. Our own exception Approach 3: Convert to new checked exception static int numberOfInputLines(String[] args) throws IOException { try { return Integer.parseInt(args[0]); } catch (ArrayIndexOutOfBoundsException e) { thrownew AMissingArgumentException(“First argument missing”); }

  36. No interface! Creating Exception Class public class AMissingArgumentException extends java.io.IOException { public AMissingArgumentException(String message) { super(message); } } Not adding any methods

  37. Checked vs. Unchecked Programmer-defined Exceptions • An exception class must be subclass of existing exception classes • Subclass of RunTimeException is unchecked • All other exceptions are checked • Java does not define exception interfaces • Neither can we as a result

  38. Handling programmer-defined exceptions try { echoLines(numberOfInputLines(args)); } catch (AMissingArgumentException e) { System.out.println(e); System.exit(-1); } catch (IOException e) { System.out.println(e); System.exit(-1); }

  39. AMissingArgumentException is subclass Removing Code Duplication try { echoLines(numberOfInputLines(args)); } catch (IOException e) { System.out.println(e); System.exit(-1); }

  40. AMissingArgumentException processed here Unreachable block Removing Code Duplication try { echoLines(numberOfInputLines(args)); } catch (IOException e) { System.out.println(e); System.exit(-1); } catch (AMissingArgumentException e) { System.out.println(e); } List exception subclass before superclass

  41. Stronger advertisement allowed Can handle IOException Interface/Class relationship public interface StringEnumeration { public boolean hasMoreElements(); public String nextElement() throws Exception; } public class AnInputStreamScanner implements StringEnumeration { ... public String nextElement() throws IOException{ return inputStream.readLine(); } } • void print (StringEnumeration stringEnumeration) { • try { • while (stringEnumeration.hasMoreElements()) • System.out.println(stringEnumeration.nextElement()); • } catch (Exception e) {…} • }

  42. Stronger advertisement allowed Interface/Class relationship public class AnInputStreamScanner implements StringEnumeration { ... public String nextElement() { try { return inputStream.readLine(); } catch (IOException e) { return “”; } } public interface StringEnumeration { ... public String nextElement() throws IOException; } • void print (StringEnumeration stringEnumeration) { • try { • while (stringEnumeration.hasMoreElements()) • System.out.println(stringEnumeration.nextElement()); • } catch (IOException e) {…} • }

  43. Weaker advertisement not allowed Cannot handle Exception Interface/Class relationship public interface StringEnumeration { public boolean hasMoreElements(); public String nextElement() throws IOException; } public class AnInputStreamScanner implements StringEnumeration { ... public String nextElement() throws Exception { return inputStream.readLine() + … ; } } • void print (StringEnumeration stringEnumeration) { • try { • while (stringEnumeration.hasMoreElements()) • System.out.println(stringEnumeration.nextElement()); • } catch (IOException e) {…} • }

  44. Weaker advertisement not allowed Not handling IOException Interface/Class relationship public interface StringEnumeration { public boolean hasMoreElements(); public String nextElement(); } public class AnInputStreamScanner implements StringEnumeration { ... public String nextElement() throws IOException{ return inputStream.readLine(); } } • void print (StringEnumeration stringEnumeration) { • while (stringEnumeration.hasMoreElements()) • System.out.println(stringEnumeration.nextElement()); • }

  45. Stronger advertisement allowed Can handle IOException Implementation/body relationship public interface StringEnumeration { public boolean hasMoreElements(); public String nextElement() throws Exception; } public class AnInputStreamScanner implements StringEnumeration { ... public String nextElement() throws Exception { return inputStream.readLine(); } } • void print (StringEnumeration stringEnumeration) { • try { • while (stringEnumeration.hasMoreElements()) • System.out.println(stringEnumeration.nextElement()); • } catch (Exception e) {…} • }

  46. Weaker advertisement not allowed Cannot handle IOException Implementation/body relationship public interface StringEnumeration { public boolean hasMoreElements(); public String nextElement() throws AMissingArgumentException; } public class AnInputStreamScanner implements StringEnumeration { ... public String nextElement() throws AMissingArgumentException { return inputStream.readLine(); } } • void print (StringEnumeration stringEnumeration) { • try { • while (stringEnumeration.hasMoreElements()) • System.out.println(stringEnumeration.nextElement()); • } catch (AMissingArgumentException e) {…} • }

  47. Exceptions in initialization • int numberOfInputLines = numberOfInputLines() • Checked exception not being handled or acknowledged • Do initialization in method • public static void main (String args) { try { numberOfInputLines = numberOfInputLines() } catch (AMissingArgumentException e) { } }

  48. IS-A Rule for Exceptions • Exception of type T1 uncaught in method body => exception of type T2, where T1 IS-A T2, acknowledged in method header • Exception of type T1 acknowledged in interface method-header => exception of type T2, where T2 IS-A T1, acknowledged in class method-header • Should overstate rather than understate bad side effects • Dizziness, headache • If you are bad, you should not say you are good. • People will be disappointed • If you are good, you can say you are bad • Don’t let people down

  49. Using EOF to terminate the loop Catching expected events try { for (;;) { String s = inputStream.readLine(); process(s); } } catch (IOException e) { }; Bad style, exception handler processes expected event more efficient: no extra if check

  50. while (enumeration.hasMoreElements()) try { System.out.println((String) enumeration.nextElement()); } catch (ClassCastException e) { e.printStackTrace());} try { while (enumeration.hasMoreElements()) System.out.println((String) enumeration.nextElement()); } catch (ClassCastException e) {e.printStackTrace());} Println terminated, catch executed, and loop continues println terminated and exception propagated to enclosing loop, which is also terminated, and catch executed Intra-method propagation

More Related