заставить доступ закрытого члена из того же класса только через метод в Java - PullRequest
3 голосов
/ 14 сентября 2011

Я хочу заставить будущих пользователей класса получать доступ к приватному члену также из будущего кода, написанного в этом классе, только через метод доступа (даже через junit или что-то подобное).

есть ли способсделать это в Java?Может кто-нибудь показать пример, если это возможно?

Ответы [ 7 ]

3 голосов
/ 14 сентября 2011

Вы не можете принудительно сделать это, но вы можете создать метод и документально подтвердить это применение в javadoc.

private int myMember;

/**
* ATTENTION: use this method instead of setting the member directly.
*/
public void setMyMember(int value) {
  this.myMember = value;
}

Также есть альтернативное решение, которое может работать.Используйте ThreadLocal, например:

private final ThreadLocal<String> member = new ThreadLocal<String>();

public void setMember(final String value) {
  member.set(value);
}

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

2 голосов
/ 14 сентября 2011

Пока поле является частью класса, любой может получить к нему доступ напрямую. Это может быть проблемой, когда мы пытаемся заставить всех (со) авторов пройти через геттеры / сеттеры, потому что эти методы выполняют некоторые преобразования, проверки или бухгалтерию. Как увеличение внутренних счетчиков.

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

@GetterSetterAccessOnly
private int value;
2 голосов
/ 14 сентября 2011

Используйте наследование, чтобы скрыть поле:

  • Проведите урок со всеми необходимыми полями и методами получения / установки. (Вы можете сделать это абстрактным)
  • Создайте дочерний класс, который наследуется от предварительного просмотра, и поскольку поле недоступно, вы принудительно используете пару получатель / установщик.
2 голосов
/ 14 сентября 2011

Если вы хотите предотвратить отражение, вы можете использовать SecurityManager.Если это не вариант, вы можете получить стек вызовов с помощью Thread.currentThread (). GetStackTrace () и проверить, что вызывающий абонент из вашего класса.

Две проблемы с этим:производительность не будет отличной.Все, что вы можете сделать в методе, который вы можете сделать внешне, поэтому самый простой способ - скопировать его содержимое без проверки.;)

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

0 голосов
/ 14 сентября 2011

Ну, если у них есть доступ к вашему коду, они могут делать все, что захотят. В худшем случае они удаляют ваши геттеры и сеттеры и вместо этого просто помещают их в открытое поле;)

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

  • Вы должны проверить, должны ли другие реализовать подклассы вместо изменения самого класса. Тогда частные поля, конечно, доступны только через сеттеры и геттеры.
  • вы можете переместить данные в другой класс и использовать ваши методы получения и установки для доступа к данным в другом классе. Делать это просто ради отсутствия данных непосредственно в вашем классе, возможно, немного нелогично, но, поскольку у вас, вероятно, есть веская причина, почему они не должны обращаться к этим самым данным, это указывает на другую ответственность. Так что рефакторинг для удовлетворения SRP это хорошая идея в любом случае.
0 голосов
/ 14 сентября 2011

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

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

0 голосов
/ 14 сентября 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...