try (
// block of statements at least one of
// which may throw an exception
if (someCondition)
throw new ExceptionName ();
// most throws are from library methods..
} catch (ExceptionName e) {
// block of statements to be executed if
// the ExceptionName exception is thrown
} ...
} catch (Exc2 e) {
// block of statements to be executed if
// the Exc2 exception is thrown
} finally {
// optional block of statements
// executed whether exception or not
}
public static f (int n) {
try (
...
int result = n * n;
return result;
} ...
} finally {
if (n == 2) return 0;
}
}
try {
...
} catch (SomeException e) {
// OK, don't worry
}
try {
...
} catch (SomeException e) {
// cannot throw exceptions
assert false; // so shouldn't get here
}
| Exception | Semantics |
|---|---|
| IllegalArgumentException | Parameter value is inappropriate |
| IllegalStateException | state is inappropriate for method call |
| NullPointerException | null value where prohited |
| IndexOutOfBoundsException | index out of range |
| ConcurrentModificationException | Modification of object has been detected where prohibited |
| UnsupportedOperationException | Object does not support method |
@throws tag
/**
* Returns the element at the specified position in this list.
* @throws IndexOutOfBoundsException if out of range.
*/
public Object get (int index) {
ListIterator it = listIterator (index);
try {
return it.next ();
} catch (NoSuchElementException e) {
throw new IndexOutOfBoundsException ("Index: " + index);
}
} // get
try {
lowLevelOperation ();
} catch (LowLevelException e) {
throw new HighLevelException (e); // has chaining constructor
}
public Object pop () {
if (size () == 0)
throw new NoSuchElementException ();
Object result = elements [--size];
elements [size] = null; // eliminate old reference
return result;
}
Stroustrup [The C++ Programming Language, 3rd Ed.. Addison-Wesley, USA, 1997] gives the following advice on C++ exception handling (pp. 386-387 and in Appendix E); these principles may be applied to Java as well:
A library shouldn't produce diagnostic output at an end user, or independently terminate a program. Instead, throw an exception and let a caller decide.
Not every program needs to be exception safe. A simple application may produce a suitable diagnostic, let the system release all acquired resources, and let the user re-run the program with a more suitable input.
Keep ordinary code and error-handling code separate.
Throw an exception to indicate failure in a constructor. Be sure that every system resource acquired in a constructor is released when throwing an exception in that constructor.
Do not throw exceptions from any clean-up code such as finally clauses. This may be difficult to ascertain when calling library methods.
Have main () catch and report all exceptions(?).
Define a class invariant to make it clear what is a valid state.
Don't destroy "old" information until its replacement has been safely produced. Only after completing the dangerous calculation, swap the new results into place.
Provide the Basic Guarantee for exception safety for all classes:
"maintain the class invariant and don't leak resourses".When possible, provide the Strong Guarantee for exception safety :
"an operation either succeeds or leaves all operands unchanged" (failure atomicity).Some primitive operations, such as object reference assignments, provide the Nothrow Guarantee for exception safety:
"always succeed without throwing an exception".Note that Nothrow Guarantee is the ultimate safety guarantee: code that cannot fail!