Multi-catch/final rethrow
joe.darcy at oracle.com
joe.darcy at oracle.com
Mon May 3 17:25:00 PDT 2010
Greetings,
As alluded to as a possibility previously [1], I'm happy to announce
that improved exception handling with multi-catch and final rethrow will
be part of an upcoming JDK 7 build. Improved exception handling is
joining other Project Coin features implemented in the repository after
successful experiences with a multi-catch implementation developed by
Maurizio Cimadamore.
Maurizio's work also revealed and corrected a flaw in the originally
proposed static analysis for the set of exception that can be rethrown [2]:
> [a] final catch parameter is treated as throwing precisely those
> exception types that
> - the try block can throw,
> - no previous catch clause handles, and
> - is a subtype of one of the types in the declaration of the catch
> parameter
Consider a final rethrow statement as below where the dynamic class of a
thrown exception differs from the static type (due to a cast in this case):
class Neg04 {
static class A extends Exception {}
static class B extends Exception {}
void test(boolean b1, boolean b2) throws B {
try {
if (b1) {
throw new A();
} else if (b2) {
throw new B();
} else {
throw (Throwable)new Exception();
}
}
catch (A e) {}
catch (final Exception e) {
throw e;
}
catch (Throwable t) {}
}
}
The set of exceptions thrown by the try block is computed {A, B,
Throwable}; therefore, the set of exceptions that can be rethrown is the
set of exceptions from the try block:
* minus A, handled by a previous catch clause, giving {B, Throwable}
* minus Throwable since Throwable is not a subtype of one of the types
declared for the catch parameter (just Exception in this case), leaving
just {B}
However, if an Exception is thrown from the try it should be caught in
the "catch(final Exception e)" clause even if the exception is cast to
Throwable since catch clauses work based on the runtime class of the
exceptions being thrown.
To address this, the third clause is changed to
> - is a subtype/supertype of one of the types in the declaration of the
> catch parameter
More formally, this clause covers computing a join over the set of
thrown exceptions, eliminating subtypes. In the example above
{Throwable} is computed as the set of exceptions being throwable from
the try block. This is then intersected with the exceptions that can be
caught by the try block, resulting in {Exception}, a properly sound result.
Very general exception types being thrown by a try block would reduce
the utility of multi-catch since only imprecise information would be
available. Fortunately, from analyzing the JDK sources, throwing a
statically imprecise exception seems rare, indicating multi-catch with
the amended specification should still be very be helpful in practice.
Today the adventurous can apply a changest [3] to a copy of the JDK 7
langtrools repository and build get a javac supporting this feature.
Otherwise, the change will appear in promoted JDK 7 builds in due
course. [4]
-Joe
[1] "Project Coin: Post-Devoxx Update, closures and exception handling,"
http://blogs.sun.com/darcy/entry/projec_coin_post_devoxx_closures
[2] "Improved Exception Handling for Java,"
http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000003.html
[3] http://hg.openjdk.java.net/jdk7/tl/langtools/rev/a6f2911a7c55
[4] http://download.java.net/jdk7/binaries/
More information about the coin-dev
mailing list