Throws clause of default constructor
Alex Buckley
alex.buckley at oracle.com
Tue Oct 28 00:20:07 UTC 2014
JLS9 would benefit from informative text about why "no throws clause"
turned into "a throws clause pertaining to unchecked exceptions only".
For this reason, it would be good to elucidate "the rule is stricter
than necessary" in JDK-8062234 itself.
The 8.8.9 text should also formulate the body of the default ctor more
precisely than "Otherwise, the default constructor simply invokes the
superclass constructor with no arguments." As you indicate in
JDK-8062234, we need to speak precisely about the superclass ctor
invocation that's performed.
One more thing. Consider the relationship of B's default ctor to A's
explicit ctor: the presence of a throws clause is a first-order
interaction, and the genericity of that clause is a second-order
interaction. A third-order interaction is when B isn't a top-level class
but rather an anonymous class extending A. Then, B has a default ctor
per 15.9.5.1 - the spec of the body is OK, and the spec of the
implicitly generated throws clause is still "correct" (no need to make a
fuss about RuntimeException here), but is there a fourth-order
interaction yet lurking?
Alex
On 10/27/2014 4:37 PM, Dan Smith wrote:
> 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