Proposal: Improved Exception Handling for Java

Neal Gafter neal at gafter.com
Fri Feb 27 21:32:14 PST 2009


[Resending in plain text]

Improved Exception Handling for Java

AUTHOR(S):

Neal M Gafter

OVERVIEW

FEATURE SUMMARY:

Catching multiple exception types: A single catch clause can now catch
more than one exception types, enabling a series of otherwise
identical catch clauses to be written as a single catch clause.
Improved checking for rethrown exceptions:  Previously, rethrowing an
exception was treated as throwing the type of the catch parameter.
Now, when a catch parameter is declared final, rethrowing the
exception is known statically to throw only those checked exception
types that were thrown in the try block, are a subtype of the catch
parameter type, and not caught in preceding catch clauses.

MAJOR ADVANTAGE:

Catching multiple exception types: Simplifies a commonly appearing
pattern of redundant code.
Improved checking for rethrown exceptions: This improvement makes it
possible to add a try-catch statement around a block of code to
intercept, process, and rethrow an exception without affecting the
statically determined set of exceptions thrown from the code.

MAJOR BENEFIT:

Greatly simplifies writing and maintaining code where intercepting or
processing exceptions is common.

MAJOR DISADVANTAGE:

One-time implementation cost for adding the features to the compiler.
Longer language specification in describing the behavior.

ALTERNATIVES:

These behaviors are approximated currently by writing a series of
identical catch clauses.  During maintenance, the set of catch clauses
must be modified so that it continues to match the set of exceptions
statically thrown in the try block.  With the proposed changes, the
catch block can be written to catch a supertype of the set of
exceptions to be intercepted, resulting in fewer catch clauses and
fewer changes required when the try block evolves.

EXAMPLES

SIMPLE EXAMPLE:

try {
    doWork(file);
} catch (final IOException|SQLException ex) {
    logger.log(ex);
    throw ex;
}

ADVANCED EXAMPLE:

Show advanced usage(s) of the feature.

DETAILS

SPECIFICATION:

The grammar of Java is extended to allow a series of exception types,
separated by the "OR" operator symbol, to be used in a catch clause:

CatchClause:
 catch ( CatchFormalParameter ) Block
CatchFormalParameter:
 VariableModifiers CatchType VariableDeclaratorId
CatchType:
 DisjunctionType
DisjunctionType:
 Type
 Type | DisjunctionType

The type system is affected as follows: For the purpose of type
checking, a catch parameter declared with a disjunction has type
lub(t1, t2, ...) [JLS3 15.12.2.5].  For the purpose of exception
checking [JLS3 11.2], a throw statement [JLS3 11.2.2] that rethrows 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 subtye of one of the types in the declaration of the catch parameter

To avoid the need to add support for general disjunctive types, but
leaving open the possibility of a future extension along these lines,
a catch parameter whose type has more than one disjunct is required to
be declared final.

COMPILATION:

A catch clause is currently compiled (before this change) to an entry
in an exception table that specifies the type of the exception and the
address of the code for the catch body. To generate code for this new
construct, the compiler would generate an entry in the exception table
for each type in the exception parameter's list of types.

TESTING:

The feature can be tested by compiling and running programs that
exercise the feature.

LIBRARY SUPPORT:

No.

REFLECTIVE APIS:

No reflective API changes are required.

OTHER CHANGES:

It would be desirable, at the same time that this change is made, to
update the non-public Tree API that can be used with APT to express
the syntax extension.

MIGRATION:

None required.  However, it would be easy to detect a series of
otherwise identical catch clauses for different types and collapse
them to a single catch clause.

COMPATIBILITY

BREAKING CHANGES:

Joe Darcy observes that the following program compiles before this
change, but not after:

try {
  throw new DaughterOfFoo();
} catch (final Foo exception) {
  try {
     throw exception; // used to throw Foo, now throws DaughterOfFoo
  } catch (SonOfFoo anotherException) { // Reachable?
  }
}

However

This breakage is compile-time-only; already-compiled programs continue
to behave as before
This kind of breakage is very unlikely to occur in practice, and
The broken code was likely wrong before, as it attempts to catch
exceptions that simply cannot occur.

EXISTING PROGRAMS:

Except as above, none.

REFERENCES

EXISTING BUGS:

No existing bugs that I am aware of.

URL FOR PROTOTYPE (optional):

An implementation of disjunctive catch parameters, but without special
handling for final catch parameters:

http://www.javac.info/

See also

Catching Multiple Exception Types: http://www.javac.info/Multicatch.html
Improved Checking for Rethrown Exceptions: http://www.javac.info/Rethrown.html



More information about the coin-dev mailing list