Почему закрытые поля в типе enum видны содержащему классу? - PullRequest
10 голосов
/ 21 февраля 2011
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);
    }
}

Существуют ли какие-либо дополнительные правила в отношении управления доступом для родительских подклассов, классов в одном и том же пакете и т. Д. В отношении этого перечисления?Где я могу найти эти правила в спецификации?

Ответы [ 3 ]

21 голосов
/ 21 февраля 2011

Он не имеет ничего общего с перечислением - он имеет отношение к закрытому доступу от содержащего типа до вложенного типа.

Из спецификации языка 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(t.x); 
        }
    }
}

... но если вы просто измените Console.WriteLine на System.out.println, скомпилирует в Java. Так что Java с частными членами немного слабее, чем C #.

7 голосов
/ 21 февраля 2011

Поскольку перечисление фактически является внутренним классом родителя.

0 голосов
/ 21 февраля 2011

Класс высшего уровня похож на деревню, все знают всех, секретов нет. Вложенные единицы в нем не изменяют этот факт.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...