220 likes | 387 Views
Exceptions: Bloch. SWE 619 Last modified Fall 2007 Saket Kaushik, Paul Ammann. Item 39: Exceptions for Exceptional Conditions. Don’t do this! try{ int i=0; while (true) { a[i++].f(); } }catch(IndexOutOfBoundsException e){} Implications for API design
E N D
Exceptions: Bloch SWE 619 Last modified Fall 2007 Saket Kaushik, Paul Ammann
Item 39: Exceptions for Exceptional Conditions • Don’t do this! try{ int i=0; while (true) { a[i++].f(); } }catch(IndexOutOfBoundsException e){} • Implications for API design • Provide state testing method instead of forcing client to catch exception. Kaushik, Ammann 2005
More Item 39: • Do this instead for (int i = 0; i < a.length; i++) { a[i].f(); } Note “State Testing method”: i < a.length Kaushik, Ammann 2005
More Item 39: • How about: try{ Iterator i = collection.iterator(); while (true) { Foo foo = (Foo) i.next(); } }catch(NoSuchElementException e){} • versus: for (Iterator i = collection.iterator(); i.hasNext();){ Foo foo = (Foo) i.next(); ... } Kaushik, Ammann 2005
Item 40: Checked vs. Unchecked • Unchecked exceptions indicate programming errors • Precondition violations • Recovery is impossible • Checked exceptions indicate recoverable conditions • Force the caller to handle the exception Kaushik, Ammann 2005
Checked vs. Unchecked (cont’d) • Use unchecked exceptions if • client has nothing to do • OutOfMemoryException • client knows better • doesn’t need try-catch block; if-then block would suffice. • Use checked exceptions if client has some reasonable action • IOException Calling code is correct, but exception can still be raised! Kaushik, Ammann 2005
Item 41: Avoid Unnecessary Use of Checked Exceptions try{ obj.action(args)} }catch(SomeCheckedException e){ throw new Error (“Assertion Error”) } // should never happen • What is the point of making a client do this? • Conditions for using checked exceptions: • Exceptional condition cannot be prevented by proper use of the API • Programmer can take some useful action Kaushik, Ammann 2005
More Item 41: Standard Transformation: if (obj.actionPermitted(args)) { obj.action(args); } else { // Handle exceptional condition } Or even simply (where appropriate): obj.action(args); // Client allows call to fail Kaushik, Ammann 2005
Item 42: Bloch’s standard exceptions • IllegalArgumentException - Inappropriate parameter; several special cases • NullPointerException (param null where prohibited) • IndexOutOfBoundsException (index param out of range) • ClassCastException • ConcurrentModificationException • Concurrent modification detected when not allowed Kaushik, Ammann 2005
More Item 42 • IllegalStateException • Object state is inappropriate for method invocation • Object may not be initialized before calling accessing its state • UnsupportedOperationException • Object does not support the method • Substitution principal Kaushik, Ammann 2005
More Item 42 • Favor the use of standard exceptions • Using your API is easier • Reading your programs is easier • Performance advantage Kaushik, Ammann 2005
Item 43: Exceptions should make sense to the caller! • Throw exceptions appropriate to the abstraction • Propagated exceptions may make no sense! • Higher layers should translate lower level exceptions try{ … }catch(LowerLevelException e){ throw new HigherLevelException(…); } Kaushik, Ammann 2005
Item 44: Document them all! • Document all exceptions • Liskov and Bloch differ partially • Bloch: document each exception thrown (using JavaDoc @throws tag) • This is semantically eqvt. to Liskov’s Effects clause • Bloch: Don’t mention unchecked exceptions in the signature • Liskov: document all exceptions in Effects clause, AND mention in signature Kaushik, Ammann 2005
Item 45: Add helpful info • Include failure-capture information in detail messages • program failure due to uncaught exception, help messages are printed • these call toString() method on exception • Create exceptions with relevant data, so that it helps developer using it. • In other words, ADD RELEVANT STATE Kaushik, Ammann 2005
Item 46: Failure Atomicity of Procedures • Failure atomicity: • A failed method invocation should leave the object in the state that it was in prior to the invocation • Ways to achieve this effect: • Design immutable objects • Check parameters for validity before performing the operation • Order the computation – parts may fail come before modification • Write recovery code – cause the object to roll back its state • Perform the operation on a temporary copy of the object Kaushik, Ammann 2005
Item 46: Atomicity of Procedures • public int addMax(int [] a, int x) throws … • //Requires: … • //Modifies: a • //Effects: … • Don’t throw exception in between modifications to state variables • Procedure should have an atomic effect • throw exception in the beginning if you are not sure you can pull it off Kaushik, Ammann 2005
More Item 46 • public Object pop() throws … { • //Requires: this != EmptyStack • //Modifies: this • //Effects: pops this and returns top Object result = elements[--size]; elements[size] = null; return result; } // Note: Client can corrupt state – oops! Kaushik, Ammann 2005
More Item 46 • public Object pop() throws … { • //Requires: • //Modifies: this • //Effects: If this empty throw ISE // else pop this and returns top if (size == 0) { throw new ISE(…); Object result = elements[--size]; elements[size] = null; return result; } // Note atomic execution, normal or exception Kaushik, Ammann 2005
Item 47: Don’t ignore exceptions • Programmers should never leave a catch block empty • Its easy to ignore exceptions, but don’t! try{ … }catch(Exception e){ } // empty catch block wont raise complaints from compiler! Don’t do this! Kaushik, Ammann 2005
More Item 47 • If its empty, its highly suspect • The purpose of exception is to force programmers handle exceptional conditions • At least have a comment which explains why its ok to ignore this exception Kaushik, Ammann 2005
Meyer’s View of Exceptions (OO Software Construction) • A procedure either succeeds or fails • If contract is satisfied, procedure succeeds • If not, procedure fails • An exception is an event that may cause a procedure to fail. • A failure of a procedure causes an exceptional return to the caller. Kaushik, Ammann 2005
More Meyer • A procedure will fail if an exception occurs, and the procedure does not recover from the exception. • Only two possible responses to an exception • Retry • Fail (Organized Panic) • Only 1 possible exception in Meyer • Failure Exception (Compare to Liskov) • A bit austere for some tastes - YMMV Kaushik, Ammann 2005