Download presentation
Presentation is loading. Please wait.
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
Argument Printer package main; public class AnArgPrinter{ public static void main(String args[]) { System.out.println(args[0]); } Exception will be reported to the user
3
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]); } Regular and error code mixed together
4
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); } Regular and error code separate
5
Printing multiple arguments: main public static void main (String args[]) { echoLines(numberOfInputLines(args)); }
6
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; } Computation and UI mixed Arbitrary legal value returned, program not halted
7
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); } Decision to halt without full context
8
Moral: Separate error detection and handling In this example –Let echo lines 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
Propagating echoLines static void echoLines (int numberOfInputLines) throws IOException { for (int inputNum = 0; inputNum < numberOfInputLines; inputNum++) System.out.println(inputStream.readLine( )); } Tells caller that passing it the exception
13
Propagating numberOfInputLines static int numberOfInputLines(String[] args) throws ArrayIndexOutOfBoundsException { return Integer.parseInt(args[0]); }
14
Handling in main public static void 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. "); } Has context IO exception not caught
15
Handling in main public static void 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. "); } Must be different names
16
Passing the buck in main public static void main (String args[]) throws IOException, ArrayIndexOutOfBoundsException { echoLines(numberOfInputLines(args)); } Bad idea as interpreter’s messages may be meaningless to the user
17
Omitting IOException in throws clause static void echoLines (int numberOfInputLines) { for (int inputNum = 0; inputNum < numberOfInputLines; inputNum++) System.out.println(inputStream.readLine( )); } Java complains IOException neither handled nor declared 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
Misleading header 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
21
Reasons for exceptions User error –Programmer cannot prevent it –Should be acked 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
Problems with Java rules Unchecked exceptions can be caused by user error static int numberOfInputLines(String[] args) { return Integer.parseInt(args[0]); }
24
Approach 1: Voluntarily list exception static int numberOfInputLines(String[] args) throws ArrayIndexOutOfBoundsException { return Integer.parseInt(args[0]); } No way to force every caller that does not handle it to ack it.
25
Approach 2: Convert to checked exception static int numberOfInputLines(String[] args) throws IOException { try { return Integer.parseInt(args[0]); } catch (ArrayIndexOutOfBoundsException e) { throw new IOException (“First argument missing”); } Exception object thrown explicitly message
26
Checked vs. Unchecked Unchecked –No rules Checked –uncaught in method body => acknowledged in method header –unacknowledged in method header => caught in method body –unacknowledged in interface method-header => unacknowledged in class method-header –Interface can be used to force method implementations to catch exceptions
27
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 “”; }
28
Interface/Class relationship public interface StringEnumeration {... public String nextElement(); } public class AnInputStreamScanner implements StringEnumeration {... public String nextElement() throws IOException{ return inputStream.readLine(); }
29
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(); } Unchecked, as most users will call hasMoreElements before nextElement()
30
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(); } Good idea to throw this exception when no more elements
31
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(); } When no more elements When next element erroneous because of user error (e.g. scanning rules violated)
32
Printing debugging information catch (ArrayIndexOutOfBoundsException e) { System.out.println(e); } catch (ArrayIndexOutOfBoundsException e) { e.printStackTrace(); } e.getMessage() Stack when exception is thrown
33
Printing stack Stack that existed when exception was thrown
34
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 (IOException e) { } }
35
Approach 2: Convert to existing checked exception static int numberOfInputLines(String[] args) throws IOException { try { return Integer.parseInt(args[0]); } catch (ArrayIndexOutOfBoundsException e) { throw new IOException(“First argument missing”); } Exception object thrown explicitly
36
Approach 3: Convert to new checked exception static int numberOfInputLines(String[] args) throws IOException { try { return Integer.parseInt(args[0]); } catch (ArrayIndexOutOfBoundsException e) { throw new AMissingArgumentException(“First argument missing”); } Our own exception
37
Creating Exception Class public class AMissingArgumentException extends java.io.IOException { public AMissingArgumentException(String message) { super(message); } No interface! Not adding any methods
38
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
39
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); }
40
Removing Code Duplication try { echoLines(numberOfInputLines(args)); } catch (IOException e) { System.out.println(e); System.exit(-1); } AMissingArgumentException is subclass
41
Removing Code Duplication try { echoLines(numberOfInputLines(args)); } catch (IOException e) { System.out.println(e); System.exit(-1); } catch (AMissingArgumentException e) { System.out.println(e); } AMissingArgumentException processed here List exception subclass before superclass Unreachable block
42
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(); } Stronger advertisement allowed void print (StringEnumeration stringEnumeration) { try { while (stringEnumeration.hasMoreElements()) System.out.println(stringEnumeration.nextElement()); } catch (Exception e) {…} } Can handle IOException
43
Interface/Class relationship public interface StringEnumeration {... public String nextElement() throws IOException; } public class AnInputStreamScanner implements StringEnumeration {... public String nextElement() { try { return inputStream.readLine(); } catch (IOException e) { return “”; } Stronger advertisement allowed void print (StringEnumeration stringEnumeration) { try { while (stringEnumeration.hasMoreElements()) System.out.println(stringEnumeration.nextElement()); } catch (IOException e) {…} }
44
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() + … ; } Weaker advertisement not allowed void print (StringEnumeration stringEnumeration) { try { while (stringEnumeration.hasMoreElements()) System.out.println(stringEnumeration.nextElement()); } catch (IOException e) {…} } Cannot handle Exception
45
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(); } Weaker advertisement not allowed void print (StringEnumeration stringEnumeration) { while (stringEnumeration.hasMoreElements()) System.out.println(stringEnumeration.nextElement()); } Not handling IOException
46
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) {…} } Can handle IOException Stronger advertisement allowed
47
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) {…} } Cannot handle IOException Weaker advertisement not allowed
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 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
Catching expected events try { for (;;) { String s = inputStream.readLine(); process(s); } } catch (IOException e) { }; Using EOF to terminate the loop Bad style, exception handler processes expected event more efficient: no extra if check
50
Intra-method propagation 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 and exception propagated to enclosing loop, which is also terminated, and catch executed Println terminated, catch executed, and loop continues
51
Terminating loop vs. statement Independent errors can be collected –5 % 2 ^ 1 Dependent errors cannot be: –5 + 2 4 / - 2
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.