I am compiling this class:
public class Test {
// No throws clause here
public static void main(String[] args) {
doThrow(new SQLException());
}
static void doThrow(Exception e) {
Test.<Exception>doThrow0(e);
Test.doThrow0(e);
}
static <E extends Exception> void doThrow0(Exception e) throws E {
throw (E) e;
}
}
Why **Test.<Exception>doThrow0(e);** this line gives error to specify throws clause (or enclose it in try-catch )
And **Test.doThrow0(e);** this line don't give any error to use throws clause
This is because type inference prefers inferring type parameters that appear in the
throwsclause to unchecked exceptions whenever possible.From JLS 18.1.3:
In the first attempt to resolution, this bound is taken into account.
In
Test.doThrow0(e), there is nothing suggesting thatEshould be a checked exception, so type inference infers it to beRuntimeException, an unchecked exception.If
doThrow0took anEas parameter instead, that establishes a relationship between the type of the argument and the type of the exceptiondoThrow0throws. NowEwould be inferred to beExceptionin the callTest.doThrow0(e).In
Test<Exception>doThrow0(e), you explicitly specified thatEshould be a checked exception. Type inference doesn't even get involved here.See also this other question where you can find examples where this "try not to infer a checked exception" is desirable.