An exception can be caught and handled using the try...catch
statement. (In fact try
statements take other forms, as described in other examples about [try...catch...finally](<http://stackoverflow.com/documentation/java/89/exceptions-and-exception-handling/25177/>)
and [try-with-resources](<http://stackoverflow.com/documentation/java/89/exceptions-and-exception-handling/1581/>)
.)
The most simple form looks like this:
try {
doSomething();
} catch (SomeException e) {
handle(e);
}
// next statement
The behavior of a simple try...catch
is as follows:
try
block are executed.try
block, then control passes to the next statement after the try...catch
.try
block.- The exception object is tested to see if it is an instance of `SomeException` or a subtype.
- If it is, then the `catch` block will *catch* the exception:
- The variable `e` is bound to the exception object.
- The code within the `catch` block is executed.
- If that code throws an exception, then the newly thrown exception is propagated in place of the original one.
- Otherwise, control passes to the next statement after the `try...catch`.
- If it is not, the original exception continues to propagate.
A try...catch
can also have multiple catch
blocks. For example:
try {
doSomething();
} catch (SomeException e) {
handleOneWay(e)
} catch (SomeOtherException e) {
handleAnotherWay(e);
}
// next statement
If there are multiple catch
blocks, they are tried one at a time starting with the first one, until a match is found for the exception. The corresponding handler is executed (as above), and then control is passed to the next statement after the try...catch
statement. The catch
blocks after the one that matches are always skipped, even if the handler code throws an exception.
The “top down” matching strategy has consequences for cases where the exceptions in the catch
blocks are not disjoint. For example:
try {
throw new RuntimeException("test");
} catch (Exception e) {
System.out.println("Exception");
} catch (RuntimeException e) {
System.out.println("RuntimeException");
}
This code snippet will output “Exception” rather than “RuntimeException”. Since RuntimeException
is a subtype of Exception
, the first (more general) catch
will be matched. The second (more specific) catch
will never be executed.
The lesson to learn from this is that the most specific catch
blocks (in terms of the exception types) should appear first, and the most general ones should be last. (Some Java compilers will warn you if a catch
can never be executed, but this is not a compilation error.)
Starting with Java SE 7, a single catch
block can handle a list of unrelated exceptions. The exception type are listed, separated with a vertical bar (|
) symbol. For example:
try {
doSomething();
} catch (SomeException | SomeOtherException e) {
handleSomeException(e);
}