Невозможно получить доступ к полю из статического расширяющегося класса, содержащегося в том же файле .java

Я не могу понять, является ли это скрытой функцией, которую я никогда не обнаруживал, или ошибкой от IntelliJ Idea.

Имея этот класс,

public class StackOverflow {
    private String abc;

    public static class StackOverflowExtended extends StackOverflow {
        public StackOverflowExtended() {
            abc = "";
        }
    }
}

IntelliJ сообщает мне, что я не могу получить доступ к abc, потому что либо у него есть частный доступ, либо потому, что я нахожусь в статическом контексте.

Как только я получаю доступ к abc через super, он начинает работать.

public class StackOverflow {
    private String abc;

    public static class StackOverflowExtended extends StackOverflow {
        public StackOverflowExtended() {
            super.abc = "";
        }
    }
}

Второе тоже не должно работать, подклассы имеют доступ к полям private своих родителей.

daniu 19.12.2018 17:45

@daniu Кажется, работает (по крайней мере, Eclipse не жалуется), может быть, потому, что StackOverflowExtended определен внутри StackOverflow? Если я помещаю StackOverflowExtended снаружи, он действительно говорит, что поле не отображается.

Mark 19.12.2018 17:47

Подклассы @daniu НЕ МОГУТ * получать доступ к закрытым полям своих родителей

balsick 19.12.2018 17:48

@balsick конечно, опечатка. Больше не могу редактировать: /

daniu 19.12.2018 17:51

в любом случае IntelliJ говорит, что можно использовать super.abc для установки значения, но javac, конечно, говорит, что нет

balsick 19.12.2018 17:52

На самом деле я пробовал это с помощью super и private abc, и у меня это работает: O

aBnormaLz 19.12.2018 17:53

@aBnormaLz с помощью какой IDE? : O

balsick 19.12.2018 17:54

Он (частный с супер) работает с javac в командной строке.

DodgyCodeException 19.12.2018 18:08

@DodgyCodeException какая версия? Я использую javac 1.8.0_181

balsick 19.12.2018 18:08

Он работает с Java 8 и 11. Вот подтверждение, что он работает с 1.8.0_112: ideone.com/8CEyTu

DodgyCodeException 19.12.2018 18:16
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
10
564
2

Ответы 2

Объем и доступность любого закрытого члена (поля, конструктора или метода) - это полное тело его объявляющего класса, включая все вложенные классы.

Если внутренний класс нестатический, он привязан к экземпляру внешнего класса, поэтому вы можете получить доступ к частной переменной экземпляра.

В вашем случае внутренний класс является статическим, поэтому вам необходимо указать экземпляр объекта внешнего класса, например super (потому что в вашем случае внутренний класс расширяет внешний класс).

Единственная «странность» состоит в том, что когда вы пытаетесь получить к нему доступ с помощью this.abc, это терпит неудачу, потому что тогда, очевидно, правило, согласно которому подклассы не могут получить доступ к частным членам своих родителей, имеет приоритет.

Здесь нет ошибок или скрытых функций. Вы, вероятно, путаете наследование и внутренние классы.

Внутренний класс нестатический может получить доступ к переменным своего внешнего класса, даже если они частные.

public class StackOverflow {
    private String abc;
    public class StackOverflowExtended extends StackOverflow {
        public StackOverflowExtended() {
            abc = "";
        }
    }
}

Статический внутренний класс не может получить доступ к полям своего внешнего класса, потому что он статичен. Он может существовать без экземпляра своего внешнего класса.

Причина, по которой super.abc работает со статическим внутренним классом, заключается в том, что он является его подклассом. Доступность, не зависящая от области видимости, опять же из-за того, что это внутренний класс.

проблема в том, что у меня это не работает. IntelliJ Idea говорит, что это нормально, javac говорит, что это не так. Я пробовал дополнительные инструменты, такие как ideone и plays.java, и они работают на их машинах. На моем javac 1.8.0_191 этого не происходит, и я не могу понять, почему

balsick 20.12.2018 09:39

Другие вопросы по теме