where either at least one catch clause, or the finally clause, must be present. The body of the try
statement is executed until either an exception is thrown or the body finishes successfully. If an exception is
thrown, each catch clause is examined in turn, from first to last, to see whether the type of the exception
object is assignable to the type declared in the catch. When an assignable catch clause is found, its block
is executed with its identifier set to reference the exception object. No other catch clause will be executed.
Any number of catch clauses, including zero, can be associated with a particular TRy as long as each clause
catches a different type of exception. If no appropriate catch is found, the exception percolates out of the
try statement into any outer try that might have a catch clause to handle it.
If a finally clause is present with a try, its code is executed after all other processing in the try is
complete. This happens no matter how completion was achieved, whether normally, through an exception, or
through a control flow statement such as return or break.
This example code is prepared to handle one of the exceptions replaceValue throws:
Object value = new Integer(8);
try {
attributedObj.replaceValue("Age", value);
} catch (NoSuchAttributeException e) {
// shouldn't happen, but recover if it does
Attr attr = new Attr(e.attrName, value);
attributedObj.add(attr);
}
The try sets up a statement (which must be a block) that does something that is normally expected to
succeed. If everything succeeds, the block is finished. If any exception is thrown during execution of the code
in the try block, either directly via a throw or indirectly by a method invoked inside it, execution of the
code inside the try stops, and the attached catch clause is examined to see whether it wants to catch the
exception that was thrown.
A catch clause is somewhat like an embedded method that has one parameter namely, the exception to be
caught. As with method parameters, the exception "parameter" can be declared final, or can have
annotations applied. Inside a catch clause, you can attempt to recover from the exception, or you can clean
up and rethrow the exception so that any code calling yours also has a chance to catch it. Or a catch can do
what it needs to and then fall out the bottom, in which case control flows to the statement after the try
statement (after executing the finally clause, if there is one).
A general catch clauseone that catches exceptions of type Exception, for exampleis usually a poor
implementation choice since it will catch any exception, not just the specific one you are interested in. Had we
used such a clause in our code, it could have ended up handling, for example, a ClassCastException as
if it were a missing attribute problem.
You cannot put a superclass catch clause before a catch of one of its subclasses. The catch clauses are
examined in order, so a catch that picked up one exception type before a catch for an extended type of
exception would be a mistake. The first clause would always catch the exception, and the second clause would
never be reached. The compiler will not accept the following code:
class SuperException extends Exception { }
class SubException extends SuperException { }
class BadCatch {
public void goodTry() {
/ This is an INVALID catch ordering /
try {
throw new SubException();
} catch (SuperException superRef) {