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

10 java enums access-control

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

在参考这个枚举时,是否有关于Parent子类,同一包中的类等的访问控制的附加规则?我在哪里可以找到规范中的规则?

Jon*_*eet 21

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

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

有趣的是,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(t.x); 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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


Pau*_*ams 7

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