Which part of JLS said anonymous classes cannot have public/protected/private member classes

前端 未结 3 2130
一向
一向 2021-02-20 08:29

Consider this piece of code:

public class TopLevelClass {
    Cloneable c = new Cloneable() {
        private int privateField;
        private void privateMethod         


        
3条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-02-20 09:07

    You have:

    1. Top-Level Class TopLevelClass : not nested (hence is named, not local, not anonymous)
    2. Second-Level Class, a no-name class that extends Clonable and is a not a member of any class: is anonymous (an inner class, is not a member, is in local scope but is not a 'local class')
    3. Third-Level Class PrivateInnerClass, a member of the anonymous class: is nested, is not local, is not anonymous, is a non-static inner class

    You are using the modifier private in (2). Your included JLS text spells out this is illegal:

    8.1.1

    The access modifier public (§6.6) pertains only to top level classes (§7.6) and to member classes (§8.5), not to local classes (§14.3) or anonymous classes (§15.9.5). The access modifiers protected and private (§6.6) pertain only to member classes within a directly enclosing class or enum declaration (§8.5).

    i.e. you can use none of these modifiers inside (in the scope of) an anonymous class.


    Answer to Extra Note 2:

    In my understanding, when the Identifier class is an XXX class, what §8.1.1 stated is restricting the modifier of Identifier, not the modifiers in other declarations in ClassBody of Identifier. Otherwise, anonymous classes even cannot have those member fields and methods.

    1. Restriction of modifier before Identifier

      • This is spelled out in 8.1.1. It clearly applies.
      • All modifiers can be applied before Identifier of a member class
      • public can be applied before top-level class Identifier
      • No modifiers can be applied before Identifier of local/anonymous classes (classes declared in local scope)

      Why is this?

      Because member classes can be referenced directly by other classes (through a 'member chain' from the top-level class), but local/anonymous classes can never be referenced externally. Local/Anonymous class declarations are hidden in a scope that is itself not accessible to any other part of the java program.

      Modifiers are only legal before a class declaration when the declaration is accessible to other classes.

    2. Restriction of modifier within ClassBody

      If a class Identifier/Declaration is not accessible to other parts of the java program, of course, the ClassBody is not accessible either.

      Hence, whenever a modifier is illegal before the Identifier, a modifier could have no possible semantic meaning within the ClassBody.

      The rules for whether a modifier is allowed within ClassBody must always be identical to the rules for whether a modifier is allowed before Identifier.

    3. So 8.1.1. restricts modifiers in both places

    :)

提交回复
热议问题