java - JLS的哪一部分说匿名类不能有 public/protected/private 成员类

  显示原文与译文双语对照的内容

考虑这段代码:

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

有一个匿名类有一个 private成员字段和 private成员方法。 它已成功编译。

然后考虑这一个:

public class TopLevelClass {
    Cloneable c = new Cloneable() {
        private class PrivateInnerClass {}
    };
}

有一个匿名类有一个 private成员类。 但是。。。

  • javac说: error: modifier private not allowed here
  • eclipse说: Illegal modifier for the local class PrivateInnerClass; only abstract or final is permitted真的局部类?

什么? 为什么匿名类不能有public, protectedprivate( 以下简称 those) 当他们可以有成员类 those成员字段和方法? Confused,我观察JLS 。 因为你,Eclipse声明,我查本地类首先:

0 .99 .3 。 本地Class Declarations

一个局部类是嵌套类( §8 ) 不属于任何类,并具有一个名称( �6 .2�6 .7 ) 。
它是编译时错误如果局部类声明包含任何访问修饰符public, protectedprivate( §6 .6 ) 或修改器 static( �15 .26 .1 ) 。

所以局部类不能具有 those修饰符。 但 PrivateInnerClass是 anonymous的成员 Cloneable,所以它不是一个局部类和仍然能够有 those修饰符。

然后我查了类修饰符

3 .1 。 类Modifiers

访问修饰符 public( §6 .6 ) 仅是sftp专用于顶级类( §7 .6 ) 和成员类( §8 .5 ),而不是到本地类( §14 .3 ) 或匿名类( �15 .9 .5 ) 。
"访问修饰符 protectedprivate( §6 .6 ) 仅是sftp专用于顶级类( §7 .6 ) 和成员类(

PrivateInnerClass所属类,它位于直接封闭类,匿名 Cloneable,因此还可以有 those修饰符在理论。 我观察以及其他部分,但我还是找不到有关规定。

所以哪一部分Java Language Specification说类匿名类不能有成员those修饰符?


Extra Note 1: 有些回答提出有关成员类和局域网类,所以我做了一个测试来断定( 除非修饰符等方面) :

  1. anonymous Cloneable未指定成员类和局部类
  2. PrivateInnerClass所属类,但不局部类

以下是我的测试代码:

public class TopLevelClass {
    Cloneable c = new Cloneable() {
        class PrivateInnerClass {}
    };

    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> c1 = Class.forName("TopLevelClass$1");
        Class<?> c2 = Class.forName("TopLevelClass$1$PrivateInnerClass");
        System.out.println(c1.isMemberClass()); // false
        System.out.println(c1.isLocalClass()); // false
        System.out.println(c2.isMemberClass()); // true
        System.out.println(c2.isLocalClass()); // false
    }
}

Extra Note 2: Review的声明普通类( JLS §8 .1 ) :

normalClassDeclaration : classModifiers opt 类Identifier TypeParameters opt super opt 接口 opt classBody 

在我理解,当 Identifier类是一个XXX类,什么 §8 .1 .1 称正在限制的修饰符 Identifier中,而不是在其他修饰符声明 ClassBodyIdentifier. 否则,甚至匿名类不能有 those成员字段和方法。

的任何回答,尤其是不同意Extra Note 2,必须指出为什么those成员字段和方法是允许的。


Extra Note 3: 如果你觉得没有这样JLS的一部分,你仍然需要提供一个可靠的文档来解释为什么those成员类是被禁止的,为什么 those成员字段和方法是允许的。


时间:

你已经错过了'包含'这个词。 privateInnerClass所属匿名类的扩充,是它本身,所以它不能有访问修饰符,在规则中包含14 .3 。

就和我们为其访问修饰符的成员,但你不了解这个。

在Eclipse错误消息错误地介绍它作为本地。

你还没有听懂,'private'就应该添加什么,即使是合法作为内部类仍然是不可见的。

我的最终答案由两个"论点

  1. 没有强限定的声明中的匿名类成员修饰符JLS 。 我如果不包含。 没有这样一部分JLS

  2. 但根据JVM specs 匿名类的成员:

jvm 7 规格: 4 .7 .6 " InnerClasses Attribute 状态:

如果C 不是一个类或接口的成员( 即如果C 是顶层类或接口( JLS §7 。6 ) 或局部类( JLS §14 。3 ) 或匿名类( JLS §15 .9 。5 ) ) 。。。

所以,根据

8 .5 Member Type Declarations

成员类是一个类,它的声明是直接用另一个类或接口声明。

匿名类 类没有成员。

所以,根据 8 .1 .1 。 类Modifiers :

访问修饰符protected和private ( §6 。6 ) 仅适于成员内部类直接封闭类

这个类不是类成员,所以他们不会有提到修饰符

...