20) May 13 - Exceptions ======================= 0) How to enforce the contract of a stack? public int pop() { Node n = top; top = n.getLink(); return n.getData(); } ... - Use tests: if (s.hasMore()) s.pop(); - Total definition: public int pop() { Node n = top; if (n==null) return 0; top = n.getLink(); return n.getData(); } - Fatal error: public int pop() { Node n = top; if (n==null) { System.out.println("Popping an empty stack!"); System.exit(-1); } top = n.getLink(); return n.getData(); } - Exceptions: public int pop() throws EmtpyStackException { Node n = top; if (n==null) throw new EmptyStackException(); top = n.getLink(); return n.getData(); } - Pre/pos conditions: balance: INTEGER -- Current balance deposit (sum: INTEGER) -- Add `sum' to account. require non_negative: sum >= 0 do balance := balance + sum ensure --one_more_deposit: deposit_count = old deposit_count + 1 updated: balance = old balance + sum end * Not every language provides a full-fledged design-by-contract syntax. Java provides assertions, which allow to simulate DbC. 1) What is the syntax of assertions? public double myDiv(double d1, double d2) { double r = d1 / d2; assert (r * d2 == d1); return r; } 2) When to use assertions? - use an assertion whenever you would have written a comment that asserts an invariant: private static void testModSwitch(String num) { int i = Integer.parseInt(num); switch (i % 3) { case 0: System.out.println("Group 1."); break; case 1: System.out.println("Group 2."); break; default: assert (i % 3 == 2); } } - place an assertion at any location you assume will not be reached: private static String getGroupName(int i) { String ans = null; switch (i % 3) { case 0: return "Group 1"; case 1: return "Group 2"; case 2: return "Group 3"; } assert false; return ans; } - Enforce pre-conditions in private methods: public static void openFiles(String[] fList) { if (fList.length == 0) { throw new IllegalArgumentException(); } for (String fName : fList) { System.out.println("Opening the file"); } } -- compare with -- private static void openFiles2(String[] fList) { assert fList.length > 0; for (String fName : fList) { System.out.println("Opening the file"); } } - Enforce post-conditions: private static BigInteger bigQuot(String n1, String n2) { BigInteger b1 = new BigInteger(n1); BigInteger b2 = new BigInteger(n2); BigInteger r = b1.mod(b2); //b2 * (b1 / b2) + r = b1 assert b2.multiply(b1.divide(b2)).add(r).equals(b1); return r; } - Verifying class invariants. E.g, making sure that a balanced tree is indeed balanced at all times. 3) How to enforece this? 4) How to compile a file that uses assertions? javac -source 1.4 MyClass.java 5) How to enable assertions? java -ea ClassName.java 6) How to disable assertions? java -da ClassName.java 7) When not to use assertions: - Do not use assertions for argument checking in public methods. Prefer exceptions. E.g: IllegalArgumentException, IndexOutOfBoundsException NullPointerException - Do not use assertions to do any work that your application requires for correct operation. e.g: assert names.remove(null); better: boolean nullsRemoved = names.remove(null); assert nullsRemoved; 8) What does this program do? 8.1) What about java TestException 6 3? 8.1) What about java TestException 6? 8.1) What about java TestException 6 0? public class TestException { public static void main(String[] args) { int i = Integer.parseInt(args[0]); int j = Integer.parseInt(args[1]); System.out.println(i / j); } } 9) What is an exception? 9.1) Conceptually? 10) What are exceptions good for? 11) In this previous program, who prints the error message? 12) What is an exception in Java? - object that inherits from Throwable Object | | Throwable / \ / \ Error Exception | | RuntimeException Error: serious errors, that one cannot recover from. 13) Example? Exception: errors that the programmer may want to catch, and that he can recover from. Some of them may be declared in methods, other may not. 14.1) Example? RuntimeException? General errors that can be throw during program execution. They do not have to be declared in methods. * Exceptions, at least as implemented in Java, are a kind of design patter. 15) What is a design pattern? 15.1) What is the exception pattern made of? - declaration - throw - try/catch 15.2) What does each of these mean? 16) How do I capture an exception? 16.1) How do I capture the ArithmeticException? public class TE1 { public static void main(String[] args) { try { int i = Integer.parseInt(args[0]); int j = Integer.parseInt(args[1]); System.out.println(i / j); } catch (ArithmeticException ae) { System.out.println("You are dividing by zero!"); ae.printStackTrace(); } } } * Exception handling has to do with the call stack: The runtime system searches the call stack for a method that contains a block of code that can handle the exception. This block of code is called an exception handler. The search begins with the method in which the error occurred and proceeds through the call stack in the reverse order in which the methods were called. When an appropriate handler is found, the runtime system passes the exception to the handler. 17.2) What about the ArrayIndexOutOfBoundsException? public class TE2 { public static void main(String[] args) { try { int i = Integer.parseInt(args[0]); int j = Integer.parseInt(args[1]); System.out.println(i / j); } catch (ArrayIndexOutOfBoundsException ie) { System.out.println("You are out of the array!"); ie.printStackTrace(); } } } 18.3) What about all the exceptions? public class TE2 { public static void main(String[] args) { try { int i = Integer.parseInt(args[0]); int j = Integer.parseInt(args[1]); System.out.println(i / j); } catch (ArithmeticException ae) { System.out.println("You are dividing by zero!"); ae.printStackTrace(); } catch (ArrayIndexOutOfBoundsException ie) { System.out.println("You are out of the array!"); ie.printStackTrace(); } } } 18.4) But These exceptions are subclasses of java.lang.Exception... public class TE3 { public static void main(String[] args) { try { int i = Integer.parseInt(args[0]); int j = Integer.parseInt(args[1]); System.out.println(i / j); } catch (Exception e) { System.out.println("You are dividing by zero!"); e.printStackTrace(); } } } 19) What happens after I execute the catch block? public class TE3 { public static void main(String[] args) { try { ... } catch (Exception e) { ... } } System.out.println("Done dividing the numbers!"); } * Exceptions are handled by chains of try/catches 20) Which catch block will be executed? public class TE2 { public static void main(String[] args) { try { int i = Integer.parseInt(args[0]); int j = Integer.parseInt(args[1]); System.out.println(i / j); } catch (ArithmeticException ae) { System.out.println("You are dividing by zero!"); ae.printStackTrace(); } catch (Exception e) { System.out.println("You are out of the array!"); e.printStackTrace(); } } } 21) And what would happen in this situation? public class TE4 { public static void main(String[] args) { try { int i = Integer.parseInt(args[0]); int j = Integer.parseInt(args[1]); System.out.println(i / j); } catch (Exception e) { System.out.println("You are out of the array!"); e.printStackTrace(); } catch (ArithmeticException ae) { System.out.println("You are dividing by zero!"); ae.printStackTrace(); } } } 22) What is an exception in Java? 22.1) How do I declare an exception? public class MyException extends Error {} public class MyTest { public static void m() { throw new MyException(); } public static void main(String args[]) { m(); } } * It is better to declare the exception as subclass of Exception: public class MyException extends Exception {} public class MyTest { public static void m() throws MyException { throw new MyException(); } public static void main(String args[]) { try { m(); } catch (MyException e) { e.printStackTrace(); } } } * I can add a constructor with a String to MyException: public class MyException extends Exception { public MyException() { } public MyException(String msg) { super(msg); } } public class MyTest { public static void m() throws MyException { throw new MyException("This is an error!"); } public static void main(String args[]) { try { m(); } catch (MyException e) { e.printStackTrace(); System.out.println("\n--//--\n"); System.out.println(e.getMessage()); } } } 23) What is the semantics of this word 'super()'? 24) What happens if I remove the try/catch block from the program above? * Some exceptions are checked, others are unchecked. Object | Throwable / \ Error *Exception | *RuntimeException * A method that can get a checked exception cannot ignore it. 25) What can this method do? - try and catch it. - or - - pass forward: public class MT { public static void m() throws MyException { throw new MyException("This is an error!"); } public static void main(String args[]) throws MyException { m(); } } 26) What are the advantages of checked exceptions? - documentation 26.1) What about disadvantages. - extra typing. Perhaps clogged code. 27) What does this program do? What about 'Error()'? public class MT1 { public static void main(String args[]) { System.out.println("1"); try { System.out.println("2"); if (true) throw new Exception(); // if (true) throw new Error(); System.out.println("3"); } catch (Exception e) { System.out.println("4"); } finally { System.out.println("5"); } System.out.println("6"); } } 28) And what about this program? public class MT2 { public static int f(boolean t) { try { if (t) throw new Exception(); return 1; } catch (Exception e) { System.out.println("2"); } finally { System.out.println("3"); } System.out.println("4"); return 2; } public static void main(String args[]) { System.out.println("1"); f(false); } }