为什么枚举类型上的私有字段对包含类可见?

public class Parent { public enum ChildType { FIRST_CHILD("I am the first."), SECOND_CHILD("I am the second."); private String myChildStatement; ChildType(String myChildStatement) { this.myChildStatement = myChildStatement; } public String getMyChildStatement() { return this.myChildStatement; } } public static void main(String[] args) { // Why does this work? System.out.println(Parent.ChildType.FIRST_CHILD.myChildStatement); } } 

在参考此枚举时,是否存在关于Parent子类,同一包中的类等的访问控制的其他规则? 我在哪里可以找到规范中的规则?

它与枚举无关 – 它与从包含类型到嵌套类型的私有访问有关。

从Java语言规范,第6.6.1节 :

否则,如果成员或构造函数被声明为private ,则当且仅当它发生在包含成员或构造函数声明的顶级类(第7.6节)的主体内时才允许访问。

例如,这也是有效的:

 public class Test { public static void main(String[] args) { Nested nested = new Nested(); System.out.println(nested.x); } private static class Nested { private int x; } } 

有趣的是,C#的工作方式略有不同 – 在C#中,私有成员只能在类型的程序文本中访问,包括来自任何嵌套类型。 所以上面的Java代码不起作用,但这会:

 // C#, not Java! public class Test { private int x; public class Nested { public Nested(Test t) { // Access to outer private variable from nested type Console.WriteLine(tx); } } } 

…但是如果您只是将Console.WriteLine更改为System.out.println,则会在Java 中进行编译。 所以Java对于私有成员来说基本上比C#更松懈。

因为枚举实际上是父类的内部类。

顶级class级就像一个村庄,每个人都认识大家,没有秘密。 其中的嵌套单元不会改变这一事实。

 class A private a; class B private b a = x; // ok new B().b = y; // ok class C extends A{} new C().a = z; // ok