Частный член Доступ Java - PullRequest
6 голосов
/ 24 марта 2009

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

    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 в рамках метода mesWithI () sub

Ответы [ 7 ]

7 голосов
/ 24 марта 2009

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

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

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

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

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

4 голосов
/ 24 марта 2009

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

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

3 голосов
/ 24 марта 2009

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

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

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

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

2 голосов
/ 24 марта 2009

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

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

1 голос
/ 24 марта 2009

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

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

0 голосов
/ 24 марта 2009

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

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

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

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

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

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

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

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

0 голосов
/ 24 марта 2009

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

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

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

...