Частный член Доступ Java

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

    class PrivateMember {
   private int i;
   public PrivateMember() {
      i = 2;
   }
   public void printI() {
      System.out.println("i is: "+i);
   }
   public void messWithI(PrivateMember t) {
      t.i *= 2;
   }
   public static void main (String args[]) {
      PrivateMember sub = new PrivateMember();
      PrivateMember obj = new PrivateMember();
      obj.printI();
      sub.messWithI(obj);
      obj.printI();
   }
}

Пожалуйста, уточните, действителен ли доступ к элементу i объекта obj в методе messWithI() элемента sub.

7 ответов

Решение

Как сказал DevSolar, он находится на (верхнем уровне) уровне класса.

Из раздела 6.6 Спецификации языка Java:

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

Обратите внимание, что нет никаких признаков того, что он ограничен членами для определенного объекта.

Начиная с Java 7, компилятор больше не разрешает доступ к закрытым членам переменных типа. Так что, если метод имеет подпись, как public <T extends PrivateMember> void messWithI(T t) тогда это будет ошибка компилятора для доступа t.i, Это не изменит ваш конкретный сценарий, однако.

Обратите внимание, что вам даже не нужен доступ на уровне источника, чтобы связываться с приватными полями. Используя java.lang.reflect.AccessibleObject.setAccessibe()весь код может получить доступ ко всем закрытым членам всего другого кода, если вы не укажете политику безопасности, которая запрещает его.

privateсамо по себе не является функцией безопасности! Это просто сильный намек другим разработчикам, что что-то является внутренней деталью реализации, от которой другие части кода не должны зависеть.

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

class PrivateAccess {
    static class InnerOne {
        private int value;
    }

    static class InnerTwo {
        int getOne ( InnerOne other ) {
            return other.value;
        }
    }
}

Обычное значение доступа к классу означает, что у вас есть доступ к частным лицам других экземпляров того же типа. В Java частный доступ определяется лексически, а не по типу.

Уровень класса. Идея состоит в том, что код класса (но не более того) знает, как обрабатывать объекты этого класса.

В любом случае, если у вас есть доступ к исходному коду класса, нет смысла "скрывать" что-либо от вас.

Как уже говорили другие, частный доступ по умолчанию ("закрытый пакет"), защищенный и, возможно, в модуле JDK 7 основан на классах (существуют очень странные правила наследования вложенных классов, которые я не могу вспомнить). Но почему?

Прежде всего, это методы, которые действуют как бинарные (или более) операторы. Для эффективной реализации они часто требуют или их легче писать без использования или изменения общедоступного API. Посмотрите на реализации equals - в хорошем коде вы найдете прямой доступ к полям с несколькими вызовами методов this, (Этот аспект производительности в настоящее время в основном не имеет значения для современных JVM, использующих общие вызовы, но проблема качества кода все еще остается.)

На той же странице сказано, что в подразделе 6.6.8 вы также можете найти следующее утверждение:

Закрытый член класса или конструктор доступен только в теле класса верхнего уровня, который содержит объявление члена или конструктора. Он не наследуется подклассами.

Член частного класса, доступ которого мы оцениваем здесь, - i.

public void messWithI () - это метод, который существует в теле класса верхнего уровня, где я был объявлен, а именно PrivateMember.

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

Это еще один способ сказать то же самое, что и Джон и Девсолар.

Модификаторы доступа для членов класса связаны с тем, где написан код (в каком пакете и в каком классе), независимо от того, к какому типу доступа предоставляется доступ: член класса или член экземпляра.

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

Просто чтобы добавить ответ DevSolar, я бы ожидал, что messWithI будет объявлен как static:

public static void messWithI(PrivateMember t) {
  t.i *= 2;

} Мне было трудно даже прочитать, что вы пытались сделать без "статического" намека... И это также облегчает ответ на ваш первоначальный вопрос - что частные члены не ограничены в области просто рассматриваемый случай.

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