Throws clause of default constructor

Dan Smith daniel.smith at oracle.com
Mon Oct 27 23:37:40 UTC 2014


Ah, this is an interesting side-effect of improving inference for 'throws' type variables.

First, here are the relevant rules about the default constructor of B (JLS 8.8.9):

"The default constructor has no throws clauses"

"the default constructor simply invokes the superclass constructor with no arguments"

"It is a compile-time error if a default constructor is implicitly declared but the superclass does not have an accessible constructor that takes no arguments and has no throws clause."

Taken literally, that last sentence means this is, trivially, an illegal program.  But I don't think javac has ever taken it literally -- if I declare a superclass constructor that 'throws RuntimeException', no error occurs in 7 or 8.

Here's a bug report for that:
https://bugs.openjdk.java.net/browse/JDK-8062234

Given that 'throws RuntimeException' is okay, note that the typing of the implicit 'super()' call in B's default constructor changed between 7 and 8.  In 7, inference determined that T:=Throwable.  In 8, inference determines that T:=RuntimeException.  (See JLS 18.4.)

So the change in errors is due to a change in inference, and is expected behavior.

—Dan

> On Oct 27, 2014, at 3:43 PM, Alex Buckley <alex.buckley at oracle.com> wrote:
> 
> Looks like a javac bug when the thrown type is a type variable.
> 
> If A's ctor is simply "A() throws Throwable {}", then JDK8 javac reports the error for B's default ctor regardless of -source version.
> 
> But make A's ctor generic and throw the type variable, and JDK8 javac only reports the error for B with -source 1.7 and below.
> 
> In fact, javac cares whether T extends {Throwable,Exception} versus a subclass of Exception. If T extends a checked exception type like java.io.IOException, then JDK8 javac actually reports the error for B regardless of -source version.
> 
> (All this on JDK8u25.)
> 
> Alex
> 
> On 10/27/2014 1:53 PM, John Spicer wrote:
>> This case gets an error with javac 7 and javac 8 with -source 1.7, but is accepted by javac 8 in normal mode.
>> 
>> I wasn't able to find the JLS change that corresponds to this.
>> 
>> Any pointers would be appreciated.
>> 
>> Thanks,
>> 
>> John.
>> 
>> class A {
>> 	<T extends Throwable> A() throws T {}
>> }
>> 
>> class B extends A {}
>> 



More information about the compiler-dev mailing list