【问题标题】:Why are private fields on an enum type visible to the containing class?为什么枚举类型上的私有字段对包含类可见?
【发布时间】:2013-02-18 17:29:52
【问题描述】:
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);
    }
}

对于父子类、同一包中的类等的访问控制是否有任何附加规则,参考此枚举?我在哪里可以找到规范中的这些规则?

【问题讨论】:

    标签: java enums access-control


    【解决方案1】:

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

    来自Java language specification, section 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(t.x); 
            }
        }
    }
    

    ...但如果您只是将 Console.WriteLine 更改为 System.out.println,则此 确实 可以在 Java 中编译。所以 Java 在私有成员方面基本上比 C# 宽松一些。

    【讨论】:

    • 谢谢乔恩。我一直听说枚举称为“特殊类类型实例”或类似术语,我想这就是为什么许多相同的规则适用于类和枚举的原因,并且规范没有提供任何额外的说明.
    • @irreputable:有趣……Java 版本在 C# 中无法运行。我猜 Nested 的主体仍然算作“顶级类的主体”。将修改答案以使其更清晰。
    【解决方案2】:

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

    【讨论】:

    • @T.J. Crowder - 稍微复杂一些;本教程描述了从 nested 类访问 enclosure 类的字段。 OP的例子是相反的。其规则在 Java 语言规范的section 6.6 中。另见this thread。
    【解决方案3】:

    顶级班级就像一个村庄,每个人都知道每个人,没有秘密。其中的嵌套单元不会改变这一事实。

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-22
      • 2020-02-16
      • 2011-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多