Change in javac handling of anonymous/local classes
Alex Buckley
alex.buckley at oracle.com
Wed Feb 27 14:35:33 PST 2013
On 2/27/2013 2:18 PM, Maurizio Cimadamore wrote:
> On 27/02/13 22:05, Alex Buckley wrote:
>> On 2/27/2013 1:40 PM, Maurizio Cimadamore wrote:
>>> On 27/02/13 21:16, Alex Buckley wrote:
>>>> - I suspect javac 1.6 and 1.7 choose TT.f3(String) because of a
>>>> different belief about shadowing. Maurizio, please comment on what's
>>>> visible at 'f3(0);'.
>>> Javac implements the so called comb-lookup [1] - supertypes are looked
>>> up before enclosing types. The problem with f1 is a glitch that has been
>>> fixed in JDK 8.
>>>
>>> Afaik the comb rule is also supported in Eclipse. I don't think there's
>>> any compiler out there that think the anonymous class has two f3
>>> members.
>>>
>>> [1] -
>>> https://blogs.oracle.com/jrose/entry/scope_ambiguities_between_outer_and
>>
>> First, I didn't say the anonymous class declaration has two f3
>> members. Obviously it has one f3 member, inherited from TT. What I
>> said is that two f3 method declarations are _visible_ from the body of
>> the anonymous class declaration, at least according to JLS 6.4.1.
>>
>> Second, the comb rule is operational in nature, and has never been
>> stated explicitly in the JLS. It should emerge from a combination of
>> class membership and inheritance (8.2, 8.4.8), scope (6.3), shadowing
>> (6.4.1), and the meaning of method names (6.5.7.1). I don't think it
>> does emerge, though perhaps I am misinterpreting shadowing in 6.4.1.
>> It's clear that compilers think X1.f3 in the enclosing scope is
>> shadowed by the inherited TT.f3. (Even though no-one actually _likes_
>> the comb rule.)
>>
>> Alex
> I think the fun happens in 15.12.2 (class or interface to search):
>
> If it is a simple name, that is, just an/Identifier/, then the name of
> the method is the/Identifier/. If the/Identifier/appears within the
> scope(§6.3)
> <http://docs.oracle.com/javase/specs/jls/se5.0/html/names.html#103228>of
> a visible method declaration with that name, then there must be an
> enclosing type declaration of which that method is a member. Let/T/be
> the innermost such type declaration. The class or interface to search is/T/.
You are quite right to point to 15.12.1 "Determine class or interface to
search". I added a link to 15.12 into the section on the meaning of
method names, to remind people to look there, but did not follow my own
hint today!
> What is the innermost type declaration where the call to f3 occurs? I'd
> say that T is the type of the anonymous inner class. Then T is the type
> to search and anything after that will take membership into account. As
> you stated, X1.f3 is not a member, so it is ignored.
>
> It follows that members in X1 are only considered when there's no
> matching method in T (the innermost type) so that the search must fall
> back to the enclosing type. Hence the comb.
Yes. The good news is that TT.f3 and X1.f3 are both visible at the point
of 'f3(0);' - no shadowing is specified to occur and no shadowing is
implemented to occur. Then, TT is the innermost enclosing type
declaration of which f3 is a member, and TT will be searched
(successfully) for an f3(int) member. Thanks again.
Alex
More information about the compiler-dev
mailing list