UPDATED: Rethrows Clause
Mark Mahieu
markmahieu at googlemail.com
Mon Mar 30 17:04:13 PDT 2009
Forgot my JLS references in the first one...
HTML version + prototype available at:
http://slm888.com
Rethrows Clause
v0.1.1
AUTHOR(S):
Mark Mahieu
OVERVIEW
FEATURE SUMMARY: Should be suitable as a summary in a language tutorial.
A new clause on method declarations which allows exception
translations (wrapping and rethrowing as a different type) to be
cleanly defined separately from the body of the method. In many
cases, checked exception type names do not then need to be repeated
in a method's throws clause and in a throw statement in the method body.
MAJOR ADVANTAGE: What makes the proposal a favorable change?
The proposal adds direct support for a common idiom in daily use by
Java programmers worldwide, allowing them to express their intentions
with greater clarity and ease. In comparison with some proposals,
this is an attempt to make dealing with checked exceptions easier by
increasing the expressiveness of exception handling code in general,
rather than by attempting to deprecate checked exceptions in favour
of unchecked exceptions.
MAJOR BENEFIT: Why is the platform better if the proposal is adopted?
There is a reduction in the amount of boilerplate Java programmers
have to read and write for code dealing with checked exceptions.
Declarations specifying both thrown and rethrown (wrapped) exceptions
are kept together, aiding comprehension of the code.
MAJOR DISADVANTAGE: There is always a cost.
As with any syntax sugar which enables an alternative way of
expressing an existing idiom, programmers may be tempted to use it
even when the existing idiom would be more appropriate.
ALTERNATIVES: Can the benefits and advantages be had some way without
a language change?
No.
EXAMPLES
SIMPLE EXAMPLE: Show the simplest possible program utilizing the new
feature.
Before:
void before() throws ConfigException {
try {
Class.forName("where.is.the.Code");
}
catch (ClassNotFoundException e) {
throw new ConfigException(e);
}
}
After:
void after()
catch ClassNotFoundException throw ConfigException {
Class.forName("here.is.the.Code");
}
ADVANCED EXAMPLE: Show advanced usage(s) of the feature.
Before:
void suspendAccount()
throws AuthorizationException,
PersistenceException {
try {
checkMyAuthoritah();
db.update(/*...*/);
log.recordInfo(/*...*/);
}
catch (InfernalDBException e) {
throw new PersistenceException(e);
}
catch (InfernalLogException e) {
throw new RuntimeException(e);
}
}
After:
void suspendAccount()
throws AuthorizationException
catch InfernalDBException throw PersistenceException,
InfernalLogException throw RuntimeException {
checkMyAuthoritah();
db.update(/*...*/);
log.recordInfo(/*...*/);
}
DETAILS
SPECIFICATION: Describe how the proposal affects the grammar, type
system, and meaning of expressions and statements in the Java
Programming Language as well as any other known impacts.
The syntactic grammar is modified to allow an optional rethrows
clause immediately prior to a MethodBody:
MethodDeclaratorRest:
FormalParameters {[]} [throws
QualifiedIdentifierList] ( ( [catch ExceptionTranslationList]
MethodBody ) | ; )
ExceptionTranslationList:
QualifiedIdentifier throw QualifiedIdentifier { ,
ExceptionTranslationList }
JLSv3 §8.4.6 : A rethrows clause lists one or more exception
translations, each translation consisting of a caught type C and a
translated type T for which all of the following must hold:
* C <: java.lang.Exception
* T < java.lang.Throwable
* Neither C nor T is a type variable.
* T has an accessible constructor suitable for rethrowing a
value of type C (see below).
* T is not the same type as C.
Any exceptions thrown by the method body which are a subtype of a
caught exception type in the rethrows clause, are rethrown as the
corresponding translated exception type.
For a given translated type T with corresponding caught type C, if T
has an accessible constructor accepting a value of type C, then the
translation is equivalent to the following:
catch (C e) {
throw new T(e);
}
Otherwise it must have an accessible no argument constructor, and the
translation is equivalent to:
catch (C e) {
throw new T().initCause(e);
}
A rethrows clause does not restrict which types may appear in a
throws clause for the same method. In particular, for a given caught
type C in the rethrows clause, it is permitted for some type C1 :> C
to also be listed in the throws clause.
JLSv3 §8.2 : The set of exception types declared to be thrown by a
method is the union of:
* the types in the throws clause
* the translated types in the rethrow clause
* the types thrown by the translated types' selected constructors
JLSv3 §11.2.2 : For the purposes of exception analysis, the set of
checked exception types which may be thrown by the method's body is
the union of:
* the types in the throws clause
* the caught types in the rethrows clause
JLSv3 §11.2.3 : It is a compile-time error if a rethrows clause
contains a translation from a checked exception type C but there
exists no checked exception type E such that all of the following hold:
* E <: C
* The method body can throw E
* No preceding translation in the rethrow clause catches E or a
supertype of E
unless C is the class java.lang.Exception.
JLSv3 §13.4.21 : Changes to the rethrows clause of methods or
constructors do not break compatibility with existing binaries; these
clauses are checked only at compile time.
COMPILATION: How would the feature be compiled to class files? Show
how the simple and advanced examples would be compiled. Compilation
can be expressed as at least one of a desugaring to existing source
constructs and a translation down to bytecode. If a new bytecode is
used or the semantics of an existing bytecode are changed, describe
those changes, including how they impact verification. Also discuss
any new class file attributes that are introduced. Note that there
are many downstream tools that consume class files and that they may
to be updated to support the proposal!
A simple desugaring could consist of enclosing the method body's
statements in a try statement, with catch clauses for each translated
exception type. For example, the following method:
Method findMethod()
catch ClassNotFoundException throw ConfigException,
NoSuchMethodException throw ConfigException {
Class<?> c = Class.forName("some.Thing");
return c.getDeclaredMethod("execute", null);
}
would be desugared to:
Method findMethod()
throws ConfigException {
try {
Class<?> c = Class.forName("some.Thing");
return c.getDeclaredMethod("execute", null);
}
catch (ClassNotFoundException e) {
throw new ConfigException(e);
}
catch (MethodNotFoundException e) {
throw new ConfigException(e);
}
}
No changes to the classfile format are required.
TESTING: How can the feature be tested?
An initial set of jtreg tests is included in the prototype.
LIBRARY SUPPORT: Are any supporting libraries needed for the feature?
No
REFLECTIVE APIS: Do any of the various and sundry reflection APIs
need to be updated? This list of reflective APIs includes but is not
limited to core reflection (java.lang.Class and java.lang.reflect.*),
javax.lang.model.*, the doclet API, and JPDA.
com.sun.source.tree.MethodTree would require updates to access the
rethrows clause's caught and translated types.
OTHER CHANGES: Do any other parts of the platform need be updated
too? Possibilities include but are not limited to JNI, serialization,
and output of the javadoc tool.
No
MIGRATION: Sketch how a code base could be converted, manually or
automatically, to use the new feature.
Catch clauses which simply wrap and rethrow an exception as another
exception type not caught in an enclosing scope, can be trivially
replaced with a rethrows clause, either manually or automatically.
It should be possible for tools to offer bidirectional conversions
such that an exception translation may be moved back into the method
body if it is subsequently decided that additional logic is required.
COMPATIBILITY
BREAKING CHANGES: Are any previously valid programs now invalid? If
so, list one.
No
EXISTING PROGRAMS: How do source and class files of earlier platform
versions interact with the feature? Can any new overloadings occur?
Can any new overriding occur?
The semantics of existing class files and legal source files are
unchanged by this feature.
REFERENCES
EXISTING BUGS: Please include a list of any existing Sun bug ids
related to this proposal.
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6534270
(similar, but emphasizes unchecked exceptions)
URL FOR PROTOTYPE (optional):
http://slm888.com/javac
More information about the coin-dev
mailing list