Change in javac handling of anonymous/local classes

John Rose john.r.rose at oracle.com
Wed Feb 27 15:45:56 PST 2013


On Feb 27, 2013, at 2:05 PM, Alex Buckley <alex.buckley at oracle.com> wrote:

> 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.)

Since we are talking about the comb rule, I will dip once more into the history of inner classes, FTR.

The original draft of the inner classes spec. anticipated the comb rule and *excluded* it, as prone to error.  (We decided that mixing inheritance and lexical scoping was a bad idea, at least for simple identifiers.)

The then-editor of the JLS disagreed with that exclusion and refrained from incorporating it into the official spec.

See excerpt below, which also includes the reason (which I alluded to earlier) for the "final variable" rule.

— John

http://web.archive.org/web/20000830111018/http://java.sun.com/products/jdk/1.1/docs/guide/innerclasses/spec/innerclasses.doc1.html
Note the final declaration. Local final variables such as array are a new feature in 1.1. In fact, if a local variable or parameter in one class is referred to by another (inner) class, itmust be declared final. Because of potential synchronization problems, there is by design no way for two objects to share access to a changeable local variable. The state variablecount could not be coded as a local variable, unless perhaps it were changed a one-element array:

        Enumeration myEnumerate(final Object array[]) {
            final int count[] = {0}; // final reference to mutable array
            class E implements Enumeration {
                public boolean hasMoreElements()
                    { return count[0] < array.length; }   ...

(Sometimes the combination of inheritance and lexical scoping can be confusing. For example, if the class E inherited a field named array from Enumeration, the field would hide the parameter of the same name in the enclosing scope. To prevent ambiguity in such cases, Java 1.1 allows inherited names to hide ones defined in enclosing block or class scopes, but prohibits them from being used without explicit qualification.)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20130227/46822fe8/attachment.html 


More information about the compiler-dev mailing list