Effective Java, Chapter 9: Exceptions

22
Effective Java, Chapter 9: Exceptions Items 57-65 Last modified Fall 2012 Paul Ammann

description

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){} - PowerPoint PPT Presentation

Transcript of Effective Java, Chapter 9: Exceptions

Page 1: Effective Java, Chapter 9: Exceptions

Effective Java, Chapter 9: Exceptions

Items 57-65 Last modified Fall 2012

Paul Ammann

Page 2: Effective Java, Chapter 9: Exceptions

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.

Page 3: Effective Java, Chapter 9: Exceptions

More Item 57 Do this insteadfor (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

Page 4: Effective Java, Chapter 9: Exceptions

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(); ... }

Page 5: Effective Java, Chapter 9: Exceptions

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

Page 6: Effective Java, Chapter 9: Exceptions

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

Page 7: Effective Java, Chapter 9: Exceptions

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!

Page 8: Effective Java, Chapter 9: Exceptions

Item 59: Avoid Unnecessary Use of Checked Exceptionstry{ 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

Page 9: Effective Java, Chapter 9: Exceptions

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

Page 10: Effective Java, Chapter 9: Exceptions

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

Page 11: Effective Java, Chapter 9: Exceptions

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

Page 12: Effective Java, Chapter 9: Exceptions

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

Page 13: Effective Java, Chapter 9: Exceptions

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;}

Page 14: Effective Java, Chapter 9: Exceptions

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

Page 15: Effective Java, Chapter 9: Exceptions

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”

Page 16: Effective Java, Chapter 9: Exceptions

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

Page 17: Effective Java, Chapter 9: Exceptions

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

Page 18: Effective Java, Chapter 9: Exceptions

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

Page 19: Effective Java, Chapter 9: Exceptions

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

Page 20: Effective Java, Chapter 9: Exceptions

More Item 64public 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

Page 21: Effective Java, Chapter 9: Exceptions

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!

Page 22: Effective Java, Chapter 9: Exceptions

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