David Evans CS201j: Engineering Software University of Virginia Computer Science Lecture 10: Programming Exceptionally
2 October 2003CS 201J Fall Last Time… No checking –Assume programmers know what they are doing Run-time checking –Check for anomalous behavior during program execution Static checking –Check at compile-time –Know properties of all possible executions before executing code
2 October 2003CS 201J Fall Exceptions in Java
2 October 2003CS 201J Fall StringSet choose public class StringSet { Vector els; // a Vector of String objects els != null els.elementType == \type(String) els.containsNull == false … public String choose () // EFFECTS: Returns an element of this. { return (String) els.firstElement (); }
2 October 2003CS 201J Fall What can go wrong… > java TestClient Exception in thread "main" java.util.NoSuchElementException at java.util.Vector.firstElement(Vector.java:450) at StringSet.choose(StringSet.java:54) at TestClient.test(TestClient.java:22) at TestClient.main(TestClient.java:4) public static void test () { StringSet s = new StringSet (); s.insert ("Alpha"); s.remove (s.choose ()); }
2 October 2003CS 201J Fall public class StringSet { Vector els; // a Vector of String objects els != null els.elementType == \type(String) els.containsNull == false … public String choose () // REQUIRES: this has at least one element // EFFECTS: Returns an element of this. { return (String) els.firstElement (); }
2 October 2003CS 201J Fall Use Exceptions to Remove Requires public String choose () throws EmptyException // EFFECTS: If this has at least one // element, returns an element of this. // Otherwise, throws EmptyException.
2 October 2003CS 201J Fall Throwing Exceptions public String choose () throws EmptyException // EFFECTS: If this has at least one element, returns an // element of this. Otherwise, throws EmptyException. { if (size () == 0) throw new EmptyException (); return (String) els.firstElement (); } What is EmptyException?
2 October 2003CS 201J Fall Exceptions are Objects public class EmptyException extends Exception { public EmptyException () { super (); } extends Exception means EmptyException inherits from the Exception type (in the Java API). Exception EmptyException We will cover subtyping and inheritance next week.
2 October 2003CS 201J Fall Catching Exceptions public class SetClient { public static void test () { StringSet s = new StringSet (); s.insert ("Alpha"); try { s.remove (s.choose ()); } catch (EmptyException e) { System.err.println ("Got EmptyException!"); System.exit (1); } System.out.println (“Done”); } Code inside the try block executes normally until it throws an exception. If no exception is thrown, execution proceeds after the catch. If the EmptyException exception is thrown, the catch handler runs.
2 October 2003CS 201J Fall Propagating Exceptions public class SetClient { public static void main (String []args) { StringSet s = new StringSet (); s.insert ("Alpha"); s.remove (s.choose ()); System.out.println (“Done”); } public class StringSet { public String choose () { return (String) els.firstElement (); } SetClient.main StringSet.choose Vector.firstElement calls NoSuchElementException throws looking for catch handler looking for catch handler looking for catch handler Exception in thread "main" java.util.NoSuchElementException at java.util.Vector.firstElement(Vector.java:450) at StringSet.choose(StringSet.java:54) at SetClient.main(SetClient.java:6)
2 October 2003CS 201J Fall Checked Exceptions Java has two types of exceptions: checked exceptions and run time exceptions Checked exceptions must be caught –Java compiler will not allow a program that could have an unchecked checked exception (so they don’t propagate to caller) Run time exceptions need not be caught –Subtype of RuntimeException –Propagate automatically up stack until caught
2 October 2003CS 201J Fall Catching Exceptions public class SetClient { public static void main (String args[]) { StringSet s = new StringSet (); s.insert ("Alpha"); System.out.println (s.choose ()); } > javac SetClient.java SetClient.java:5: unreported exception EmptyException; must be caught or declared to be thrown
2 October 2003CS 201J Fall Guidelines Use unchecked exceptions when the exception is not part of the client interface: –Specified precondition is violated –Defensive programming Assertion violated Use checked exceptions when: –An unusual situation prevents the implementation from satisfying the normal postcondition
2 October 2003CS 201J Fall Does Java API follow our guidelines? public final Object firstElement() // EFFECTS: If this vector has no elements, throws // NoSuchElementException. Otherwise, returns // the first component of this vector. public class StringSet { Vector els; // a Vector of String objects public String choose () // EFFECTS: Returns an element of this. { return (String) els.firstElement (); } NoSuchElementException is a Runtime Exception, so there is no compiler warning for choose.
2 October 2003CS 201J Fall Pop Quiz!
2 October 2003CS 201J Fall Specifying Exceptional Behavior Checked exceptions are part of the client interface: should be specified ESC/Java exsures annotation: N (ExceptionType) E If the procedure returns normally, the postcondition N is true. If the procedure throws an exception of type ExceptionType, E is true.
2 October 2003CS 201J Fall Specifying Choose public String choose () throws EmptyException \result != null (EmptyException) numEntries == 0 { if (size () == 0) throw new EmptyException (); return (String) els.firstElement (); }
2 October 2003CS 201J Fall Exceptions Considered Harmful Interfaces are more complicated – caller needs to worry about possible exceptions as well as result Makes it harder to understand programs –Control flow jumps around like a goto
2 October 2003CS 201J Fall PS2 AverageLength public class AverageLength { public static void main String args[]) throws RuntimeException { String filename = args[0]; try { FileInputStream infile = new FileInputStream (filename); StringTable names = new StringTable (infile); int numnames = names.size (); int totallength = 0; for (int index = 0; index <= numnames; index++) { String name = names.getNthLowest (index); totallength = totallength + name.length (); } System.out.println ("The average name length is: " + (double) totallength / numnames); } catch (FileNotFoundException e) { System.err.println ("Cannot find file: " + filename); System.exit (1); }
2 October 2003CS 201J Fall Exceptions Considered Helpful Provide a way to deal with abnormal conditions –Better than returning “special” values since caller may forget to check for them Allow you to deal with errors (e.g., file not found) up the call stack where more context information is available Separate normal code from error handling
2 October 2003CS 201J Fall Charge PS4 Design Documents due today In Section Friday, you will discuss your design with another team –Similarities and differences –What is better/worse about each design –What will make it more/less difficult to implement correctly