Вопрос

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

    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

Это было полезно?

Решение

Как сказал 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 частный доступ определяется лексически, а не по типу.

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

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

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

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

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

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

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

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

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

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

публичный недействительный messWithI() это метод , который существует в теле класса верхнего уровня , где i было объявлено, что, именно, Личный член.

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top