Ответ 1
Это ошибка в учебнике, или я, может быть, не понимаю что-то хорошее?
Вы прекрасно понимаете. В лучшем случае страница руководства вводит в заблуждение.
Здесь есть два отдельных понятия:
-
Имеете ли вы разрешение на доступ к предмету в рамках правил управления доступом Java (например, private, package-private, protected, public).
-
Значение "статический". Экземпляр "внутреннего" вложенного класса всегда связан с экземпляром охватывающего класса (сохраняя ссылку на экземпляр охватывающего класса в скрытом поле экземпляра внутреннего класса). У "статического" вложенного класса этого нет.
На странице руководства запутаны два понятия.
Вложенный класс является членом его охватывающего класса.
Ага.
Нестатические вложенные классы (внутренние классы) имеют доступ к другим членам охватывающего класса, даже если они объявлены частными. Статические вложенные классы не имеют доступа к другим членам входящего класса.
Нету.
Поставляя экземпляр самостоятельно, вы видите, что статические классы действительно имеют доступ к членам охватывающего класса, включая поля частных экземпляров, поэтому почему a.x++;
в вашем примере компилируется. Этот доступ.
Используя слова "доступ" и "частный", параграф настоятельно предлагает говорить о контроле доступа в определении, указанном в Спецификации языка Java. Но это не так. Он только пытается объяснить понятие № 2 о том, как экземпляры охватывающих классов связаны с вложенными классами. И даже тогда это все еще неправильно, потому что статические вложенные классы, безусловно, имеют доступ к статическим членам охватывающего класса, о которых в абзаце говорится, что они этого не делают. Тот, кто написал эту страницу, был неаккуратным.
Примечание. Статический вложенный класс взаимодействует с членами экземпляра его внешнего класса (и других классов), как и любой другой класс верхнего уровня. По сути, статический вложенный класс поведенчески является классом верхнего уровня, который был вложен в другой класс верхнего уровня для удобства упаковки.
Этот параграф все еще говорит о том, что означает статические средства. Он не пытается ничего сказать о контроле доступа, хотя он может быть неправильно понят.
Вот правильное правило контроля доступа, данное JLS§6.6.1. Определение доступности:
[Если] член или конструктор объявлен
private
, доступ [..] разрешен только в том случае, если он встречается внутри тела класса верхнего уровня (§7.6), который включает объявление члена или конструктора.
Это определение на удивление коротко, но оно охватывает все, что здесь имеет значение.
Это означает, что все вложенные классы (потому что они "находятся внутри тела класса верхнего уровня") имеют доступ ко всем членам и конструкторам охватывающего класса независимо от того, является ли вложенный класс статическим или экземпляром, и независимо от того, доступная вещь является статикой или экземпляром.
Кроме того, все вложенные классы также имеют доступ ко всем членам и конструкторам всех других вложенных классов в одном классе верхнего уровня.
И класс верхнего уровня имеет доступ ко всем членам и конструкторам всех классов, вложенных в него.
Предложение JLS, которое я цитировал, относится к private
доступу. Но если член или конструктор не является private
, то его уровень доступа может быть более разрешительным, по крайней мере, доступ к пакету, а классы, заключенные в один и тот же тип верхнего уровня, неизбежно находятся в одном и том же пакете, поэтому они будут доступны для каждого другие даже без специального лечения.
В принципе, класс верхнего уровня (не закрытый) и все внутри него составляют гнездо. В принципе, все внутри этого гнезда может получить доступ ко всему остальному в нем. Если это член экземпляра, вам также нужно как-то сначала получить экземпляр, но это всегда верно.