1 / 22

Effective Java, Chapter 9: Exceptions

Effective Java, Chapter 9: Exceptions. Items 57-65 Last modified Fall 2012 Paul Ammann. Item 57: Use Exceptions only for Exceptional Conditions. Don’t do this! try{ int i=0; while (true) { range[i++].climb(); } }catch(IndexOutOfBoundsException e){}

elma
Télécharger la présentation

Effective Java, Chapter 9: 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. Effective Java, Chapter 9: Exceptions Items 57-65 Last modified Fall 2012 Paul Ammann

  2. Item 57: Use Exceptions only for Exceptional Conditions • Don’t do this! try{ int i=0; while (true) { range[i++].climb(); } }catch(IndexOutOfBoundsException e){} • Note that code may hide unrelated exception! • Implications for API design • A well designed API must not force its clients to use exception handling for ordinary flow control • Provide state testing method instead of forcing client to catch exception.

  3. More Item 57 • Do this instead for (Mountain m: range) { m.climb(); } Note: • (implicit) “State Testing” method: i < range.length • No possibility of unintentionally hiding IndexOutOfBoundsException from climb() • Bottom line: Don’t use exceptions for ordinary flow control

  4. More Item 57 • 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(); ... }

  5. More Item 57 • Two basic options • State testing method • Doesn’t work in concurrent environment • State may change between state test and actual call • May be undesirable if state testing method is as much computation as actual call • Then, it’s better to have a distinguished return value • Distinguished return value • May not be an unused special value • Example: “null” for Object return types • Iterator next() method can legitimately return “null” • Faulty use of distinguished return value model harder to detect

  6. Item 58: 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

  7. More Item 58 • 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!

  8. Item 59: 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

  9. More Item 59 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

  10. Item 60: Favor Use of Standard Exceptions • IllegalArgumentException - Inappropriate parameter; several special cases • NullPointerException (param null where prohibited) • IndexOutOfBoundsException (index param out of range) • ClassCastException

  11. More Item 60 • IllegalStateException • Object state is inappropriate for method invocation • Object may not be initialized before calling accessing its state • Special subtype: ConcurrentModificationException • Concurrent modification detected where not allowed • UnsupportedOperationException • Object does not support the method • Substitution principal

  12. More Item 60 • Reasons to use standard exceptions: • Using your API is easier • Reading your programs is easier • Performance advantage (relatively minor) • No additional namespace to manage • Note that standard Java exception list is more than the 6 mentioned in Bloch

  13. Item 61: Throw Exceptions Appropriate to the Abstraction • Propagated exceptions may make no sense • Higher layers should translate lower level exceptions // Bad example: public int min (int[] a) { int minVal = a[0]; // Bad: Throws IndexOutOfBoundsException for (int val: a) {if (val < minVal) minVal = val;} return minVal; }

  14. More Item 61: Exception Chaining Transformation: try { // Use low level abstraction to satisfy contract } catch (LowerLevelException cause) { throw new HigherLevelException (cause); } • Achieves 2 very different goals • Gives client exception at expected level of abstraction • Also preserves low level detail for failure analysis

  15. Item 62: Document All Exceptions Thrown by Each Method • Checked Exceptions: • Declare (required by compiler) • And Document (with @throws tag in JavaDoc) • Unchecked Exceptions: • Document (with @throws tag in JavaDoc) • Don’t shortcut with superclass exceptions • Example: Don’t catch “Exception” instead of NullPointerException • Ok to document common exceptions at class level • Example: “All methods in class throw NullPointerException if a null object reference is passed in any parameter”

  16. Item 63: Include Failure-Capture Information in Detail Messages • Uncaught exceptions result in printing of stack trace, including “detail” messages • These messages should contain values of all parameters that “contributed to the exception” • In other words, include relevant state information • Example: IndexOutOfBoundsException includes upper bound, lower bound, and offending index

  17. Item 64: Strive for Failure Atomicity • 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 that 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

  18. More Item 64: public int addMax(List<Integer> list, Integer x) throws … //pre: true //post: if x is not max w.r.t. list, throw IAE // else append x to list • 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

  19. More Item 64 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!

  20. More Item 64 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

  21. Item 65: 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!

  22. More Item 65 • 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

More Related