Частное поле в подклассе доступно в суперклассе

Написано на JLS (см. раздел 8.3):

«Частное поле суперкласса может быть доступно для подкласса, например, если оба класса являются членами одного и того же класса. Тем не менее, частное поле никогда не наследуется подклассом».

Не могли бы вы привести пример этого утверждения?

Я знаю, что мы можем написать:

public class MyClass {
    private int x = 1;

    public void testExample(MyClass m) {
        m.x = 2;
    }
}

Здесь мы получаем доступ к частному полю m.x, но у нас нет «Суперкласса» - «Подкласса».


person Vitaly    schedule 28.08.2015    source источник
comment
см. также groups.google.com/d/msg/java- lang-fans/KVmmgeSCHkA/7nAQolGcsjwJ   -  person ZhongYu    schedule 28.08.2015


Ответы (2)


Речь идет о вложенных классах - вот пример:

public class Test {
    public static void main(String[] args) {
        new Subclass(10).foo();
    }

    static class Superclass {
        private int x;

        Superclass(int x) {
            this.x = x;
        }
    }

    static class Subclass extends Superclass {
        Subclass(int x) {
            super(x);
        }

        public void foo() {
            Superclass y = this;
            System.out.println(y.x);
        }
    }
}

Это действительно из-за JLS 6.6:

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

Здесь использование x находится в теле Test, который является классом верхнего уровня, содержащим объявление x... хотя, если вы попытаетесь использовать x без уточнения или просто this.x, это не удастся... именно потому, что x не является на самом деле унаследовано (согласно приведенной вами спецификации).

person Jon Skeet    schedule 28.08.2015
comment
не ошибка компиляции - элемент this.x не существует, потому что x не наследуется. - person ZhongYu; 28.08.2015
comment
@bayou.io: Ага, хороший улов и отличный пример именно того, что цитируется в вопросе :) - person Jon Skeet; 28.08.2015
comment
Спасибо, Джон, я думаю, ты прав. И эта проблема является частным случаем более общего правила: все вложенные классы имеют доступ ко всем закрытым полям/методам других вложенных классов. - person Vitaly; 29.08.2015
comment
@Vitaly: В том же внешнем классе, да. - person Jon Skeet; 29.08.2015

«Видимость» метода — как следует из названия — это то, где методы и переменные «видимы» для программиста. Как правило, переменные области действия внутри класса всегда видны в определении класса, даже если они объявлены закрытыми и на них ссылается созданный объект (не «этот») этого класса.

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

private static long seedUniquifier() {
    // L'Ecuyer, "Tables of Linear Congruential Generators of
    // Different Sizes and Good Lattice Structure", 1999
    for (;;) {
        long current = seedUniquifier.get();
        long next = current * 181783497276652981L;
        if (seedUniquifier.compareAndSet(current, next))
            return next;
    }
}

(Получено из исходного кода Sun JDK)

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

Итак, в общем, вне зависимости от того, объявлена ​​переменная приватной или нет, следующий код:

public class Test {
    private float internalValue;
    public boolean isBigger(Test t) {
        return internalValue > t.internalValue;
    }
}

Всегда будет действительным.

person Xirema    schedule 28.08.2015
comment
В вашем примере осуществляется доступ к частному полю из кода в классе, который его объявляет. Я не верю, что это то, о чем спрашивал ОП. - person Jon Skeet; 28.08.2015