2015-04-29 4 views
3

Junior в Java; используя отражение можно получить доступ к закрытым полям (не спрашивая, как, Question 1 и Question 2) Хорошо.Java: доступ к частному полю через отражение (поведение)

Мои вопросы связаны с характером этого поведения.

  1. Есть ли какие-либо ограничения? Могу ли я получить доступ к любому полю любого .class, с которым я сталкиваюсь?
  2. Во время моего кода, как только вы установите видимость поля, давайте скажем «public», изменен ли он навсегда или только до конца контекста (метод, если, для ...)? Код ниже
  3. Это ok для всех? Я имею в виду, пожилые программисты StackOverflow, это нарушение безопасности?

Код [Изменено]:

Field f = obj.getClass().getDeclaredField("field"); 
    if (...) { 
    f.setAccessible(true); 
    // f IS accesible 
    } 
    // is f accesible? 
+1

Есть ситуации, когда отражение является нарушением. Одной из ситуаций, которая приходит на ум, является создание нескольких экземпляров класса «Singleton» путем доступа к его «частному» конструктору посредством отражения. – CKing

+3

Что вы подразумеваете под «* Во время моего кода, как только вы установите видимость поля, чтобы сказать« public », *«? Если вы ссылаетесь на 'f.setAccessible (true)', то вы предоставляете доступ к этому конкретному экземпляру 'Field' для поля, которое он представляет. Если вы создадите еще один экземпляр «Filed», который будет ссылаться на одно и то же поле (независимо от 'setAccessible (true)' был вызван в предыдущем экземпляре Field), этот новый экземпляр не будет иметь доступ к закрытому полю. – Pshemo

+0

@ Четан Кингер точно! Если что-то спроектировано как личное ... Пусть оно будет приватным. В случае частного атрибута ... попробуйте вызвать реальный получатель. Pshemo, в конце контекста, который вы вызываете setAccessible, он все еще доступен (редактирование моего вопроса). – Manu

ответ

3

Есть ли какие-либо ограничения?

Да - вам нужно несколько JVM permissions (прежде всего accessDeclaredMembers и suppressAccessChecks, отмеченный большими, жирные предупреждения в документации) для этой работы; если ваш профиль безопасности JVM несколько строгий (скажем, широкозаветные апплеты), ваш код не будет работать, потому что эти разрешения не будут доступны.

Становится ли оно изменено навсегда?

Да, если ваша программа продолжает работать, поля останутся доступными (если вы продолжаете использовать тот же экземпляр Field, где вы изменили разрешения доступа).

Плохо ли?

Не обязательно. Он позволяет java-коду сериализовать и де-сериализовать объекты с частными полями, что позволяет сложное издевательство, которое может упростить тестирование, оно позволяет заглянуть в места, в которые вы в противном случае не могли бы заглянуть. Однако, поскольку это нарушает ожидания, вы должны использовать его экономно и убедиться, что пользователи знают, что вам требуются дополнительные разрешения и «смотрят под капот». Документы (см. Выше) достаточно четко заявляют, что это считается рискованным, и что это должно быть разрешено только в том случае, если вы знаете, что делаете.

+0

"* Будет ли изменено навсегда? Да, до тех пор, пока ваша программа продолжает работать, поля будут оставаться доступными. *" Это применяется только для доступа к этому полю экземпляром поля, в котором вызывается 'setAccessible (true)' (и не было выбрано «SecurityException»). Мы по-прежнему не сможем напрямую обращаться к частному полю (без отражения). – Pshemo

+0

Спасибо, что указали, что вне - обновленный ответ. – tucuxi

Смежные вопросы