Действительно ли частные методы безопасны?


в Java the private модификатор доступа считают безопасным, так как он не виден за пределами класса. Тогда внешний мир тоже не знает об этом методе.

но я думал, что отражение Java может использовать, чтобы нарушить это правило. Рассмотрим следующий случай:

public class ProtectedPrivacy{

  private String getInfo(){
     return "confidential"; 
  }

}  

теперь из другого класса я собираюсь получить информация:

public class BreakPrivacy{

   public static void main(String[] args) throws Exception {
       ProtectedPrivacy protectedPrivacy = new ProtectedPrivacy();
       Method method = protectedPrivacy.getClass().getDeclaredMethod("getInfo", null);
       method.setAccessible(true);
       Object result = method.invoke(protectedPrivacy);
       System.out.println(result.toString());
   }
} 

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

но моя точка зрения становится недействительной, так как ниже строки кода.

Method method[] = new ProtectedPrivacy().getClass().getDeclaredMethods();

вот этот method[] содержит все, что нужно делать прежде всего. Мой вопрос в том, есть ли способ избежать такого рода вещей, используя отражение Java?

я цитирую какой-то момент из Java Документация чтобы прояснить мой вопрос.

советы по выбору уровень доступа:

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

7 92

7 ответов:

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

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

модификаторы доступа не имеют ничего общего с безопасностью. На самом деле вы можете и должны рассматривать модификаторы доступа как обратную сторону безопасности-это не защита ваших данных или алгоритмов, а защита людей от требования знать о ваших данных и алгоритмах. Вот почему модификатором по умолчанию является package - если они работают над пакетом, им, вероятно, уже нужно знать.

наряду со знанием данных и методов вашего кода, приходит ответственность, чтобы знать, когда и как его использовать. Вы не ставите private на свой метод inIt, чтобы кто-то не узнал об этом, вы делаете это потому, что (а) они не узнают, что вы только называете это после foo и только если bar = 3.1415 и (Б) потому что им не нужно знать об этом.

модификаторы доступа могут быть суммированы в простой фразе " TMI, чувак, I так не нужно было этого знать".

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

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

любой фрагмент кода (написанный вами или другими), который пытается получить доступ к private член вышеуказанного класса по существу роет свою собственную могилу. private члены не делают часть общественные API и могут быть изменены без предварительного уведомления. Если клиент случайно потребляет один из таких частных членов таким образом, как указано выше, он сломается, если он обновится до более новой версии API, в которой был изменен частный член.

с объектом, приходит ответственность. Есть вещи, которые ты Не могу сделать, и вещи, которых вы can сделать, но вы Не стоит do.

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

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

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

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

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

Как только вы выпустите свой код, люди смогут понять, как он работает. Нет никакого способа "скрыть" логику, если вы в конечном итоге хотите, чтобы код выполнялся на компьютере. Даже компиляция в двоичный файл - это уровень обфускации.

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