Relates :
|
|
Relates :
|
|
Relates :
|
15.9 says the thrown types of a class instance creation expression include E, where "E is listed in the throws clause of the type of the constructor that is invoked". This doesn't account for the possibility that E may be a type variable (one of the type parameters of the constructor). The text needs to be clarified, and 15.9.3 in particular needs to describe how the throws clause may be derived from inferred type arguments. It's particularly unclear whether E should be erased due to unchecked argument conversion, as in 15.12.2.6. I believe the scope of this problem is restricted to the case of type variables appearing as thrown types. 8.1.2 prohibits exception classes from being generic, so we can never have throws MyException<T>, etc. I wrote a test to see what implementations did. The results demonstrate that the correct behavior is very poorly understood. /** * Testing the following from JLS 15.12.2.6: * If unchecked conversion was necessary for the method to be applicable * then the throws clause is composed of the erasure (4.6) of the types * in the method���s declared throws clause. */ public class UncheckedInvocation { static <E extends Exception> Iterable<E> empty(Iterable<E> arg) throws E { for (E e : arg) throw e; return arg; } <E extends Exception> UncheckedInvocation(Iterable<E> arg) throws E { empty(arg); } /** * Method invocation, no unchecked * Specified thrown: RuntimeException * javac: RuntimeException * Eclipse: RuntimeException */ void m1() { Iterable<RuntimeException> i = java.util.Collections.emptyList(); empty(i); } /** * Method invocation, unchecked, inferred arguments * Specified thrown: Exception * javac: E (!) * Eclipse: Exception */ void m2() { Iterable i = java.util.Collections.EMPTY_LIST; empty(i); } /** * Method invocation, unchecked, explicit arguments * Specified thrown: Exception * javac: RuntimeException * Eclipse: RuntimeException */ void m3() { Iterable i = java.util.Collections.EMPTY_LIST; UncheckedInvocation.<RuntimeException>empty(i); } /** * Constructor invocation, no unchecked * Specified thrown: RuntimeException (unclear) * javac: E (!) * Eclipse: RuntimeException */ void m4() { Iterable<RuntimeException> i = java.util.Collections.emptyList(); new UncheckedInvocation(i); } /** * Constructor invocation, unchecked, inferred arguments * Specified thrown: Exception? (unclear) * javac: E (!) * Eclipse: Exception */ void m5() { Iterable i = java.util.Collections.EMPTY_LIST; new UncheckedInvocation(i); } /** * Constructor invocation, unchecked, explicit arguments * Specified thrown: Exception? (unclear) * javac: E (!) * Eclipse: RuntimeException */ void m6() { Iterable i = java.util.Collections.EMPTY_LIST; new <RuntimeException>UncheckedInvocation(i); } }
|