2009-08-06 1 views
41

Рассмотрим следующий пример:Почему для доступа к частным полям Java через отражение?

import java.lang.reflect.Field; 

public class Test { 

    public static void main(String[] args) { 
     C c = new C(); 
     try { 
      Field f = C.class.getDeclaredField("a"); 
      f.setAccessible(true); 
      Integer i = (Integer)f.get(c); 
      System.out.println(i); 
     } catch (Exception e) {} 
    } 
} 

class C { 
    private Integer a =6; 
} 

Это кажется нелогичным, что вам позволено получить доступ к частным поля классов с отражением. Почему такая функциональность доступна? Разве не «опасно» разрешить такой доступ?

ответ

55

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

+11

+1 для «для определения области, а не для безопасности». – skaffman

+4

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

+0

, так что все, инкапсуляция или я должен сказать - скрытие данных - это все о скриншоте и ничего общего с безопасностью, даже если вы предоставляете свои API как стороннюю банку –

8

Отражение опасно. Период.

Какой смысл ограничивать полезность действительно опасной системы ради столь незначительно повышенной безопасности?

Кроме того, автоматическая сериализация требует способности «высасывать мозги» из любого класса; игнорирование модификаторов доступа является необходимостью в этом случае.

3

От: http://java.sun.com/docs/books/tutorial/reflect/

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

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

3

Из description of the java.lang.reflect пакета:

Классы в этом пакете, наряду с java.lang.Class размещения приложений, таких как отладчики, переводчиков, инспекторов объектов, класс браузеров и услуг, таких как Object Сериализация и JavaBeans для чего нужен доступ к открытым объектам целевого объекта (в зависимости от его класса времени исполнения ) или членов, объявленных данным классу.

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

Да, отражение вообще может быть опасным, так как оно может подвергать внутренности классов и объектов.

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

10

Да, это не приятно, но это позволяет работать с такими ракурсами, как Java Serialization.

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

Я считаю, что функциональные возможности могут быть отключены через SecurityManager

http://javabeans.asia/2008/10/12/how_to_set_securitymanager_and_java_security_policy_programmatically.html

21

Оба getDeclaredField() и setAccessible() фактически проверяются менеджером безопасности и сгенерирует исключение, когда ваш код не имеет права делать это. Чаще всего вы этого не заметите, потому что код Java часто запускается без администратора безопасности.

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

+0

Вы говорите, что «Java-код часто запускается без администратора безопасности». У вас нет администратора безопасности по умолчанию? – firstthumb

+1

Woah ... «важный» и «апплет» в том же предложении. То были времена. Я оставлю это так, как свидетельство того, как изменяются времена :-) –

4

Отражение - это полный API для доступа к классам. Частные члены и все.

В случаях, когда вы не доверяете запущенному вами коду (апплеты и т. П.), Вы можете вообще не использовать код. См. this Stack Overflow question.