Change in javac handling of anonymous/local classes (original) (raw)

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/scopeambiguitiesbetweenouterand 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