gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-10-30 21:27:35 24 4
gpt4 key购买 nike

考虑这段代码:

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成员(member)类。然而……

  • 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成员字段和方法? 困惑,我调查了 JLS。由于 Eclipse 所说,我调查了 local classes第一:

14.3. Local Class Declarations

A local class is a nested class (§8) that is not a member of any class and that has a name (§6.2, §6.7).
It is a compile-time error if a local class declaration contains any of the access modifiers public, protected, or private (§6.6), or the modifier static (§8.1.1).

所以本地类不能有those修饰符。但是PrivateInnerClass 匿名Cloneable的成员, 所以它不是本地类并且仍然能够拥有 those修饰符。

然后我查看了class modifiers :

8.1.1. Class Modifiers

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

但是PrivateInnerClass是一个成员类,它在一个直接封闭的类中,匿名Cloneable , 所以它仍然可以有 those理论上的修饰符。其他部分我也看了,还是没找到相关规定。

那么 Java 语言规范的哪一部分说匿名类的成员类不能有 those修饰符?


附注1:有些回答对成员类和局部类争论不休,所以我做了一个测试可以得出结论(除非修饰符很重要):

  1. 匿名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
}
}

附注2:查看普通类(JLS §8.1)的声明:

NormalClassDeclaration:    ClassModifiersopt class Identifier TypeParametersopt                                               Superopt Interfacesopt ClassBody

据我了解,当 Identifier类是XXX类,什么§8.1.1 stated 正在限制 Identifier 的修饰符,而不是 ClassBody 中其他声明中的修饰符的 Identifier .否则,匿名类甚至不能有those成员字段和方法。

任何答案,尤其是不同意附注 2 的答案,都必须指出原因 those允许成员字段和方法。


附注3:如果您认为JLS没有这部分,您仍然需要提供一份可靠的文件来解释为什么those成员类被禁止以及为什么those允许成员字段和方法。


最佳答案

你有:

  1. 顶级类 TopLevelClass :未嵌套(因此被命名,不是本地的,不是匿名的)
  2. 二级类,一个扩展 Clonable 并且不是任何类的成员的无名类:是匿名的(内部类,不是成员,在本地范围但不是“本地类”)
  3. 三级类PrivateInnerClass,匿名类的成员:是嵌套的,不是本地的,不是匿名的,是非静态的内部类

您在 (2) 中使用了修饰符 private。您包含的 JLS 文本说明这是非法的:

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

即您不能在匿名类的内部(范围内)使用这些修饰符中的任何一个。


额外注释 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. 标识符前修饰符的限制

    • 这在 8.1.1 中有详细说明。它显然适用。
    • 所有修饰符都可以应用在成员类的标识符之前
    • public 可以在顶级类标识符之前应用
    • 在本地/匿名类(在本地范围内声明的类)的标识符之前不能应用任何修饰符

    这是为什么?

    因为成员类可以被其他类直接引用(通过顶级类的“成员链”),但是本地/匿名类永远不能被外部引用。本地/匿名类声明隐藏在 java 程序的任何其他部分本身无法访问的范围内。

    当其他类可访问时,修饰符在类声明之前是合法的。

  2. 修饰符在ClassBody内的限制

    如果java程序的其他部分不能访问一个类标识符/声明,当然,ClassBody也不能访问。

    因此,只要标识符之前的修饰符是非法的,修饰符在 ClassBody 中就没有可能的语义意义。

    ClassBody 中是否允许修饰符的规则必须始终与标识符之前是否允许修饰符的规则相同

  3. 所以 8.1.1。在两个地方限制修饰符

:)

关于java - JLS哪一部分说匿名类不能有public/protected/private成员类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17484834/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com