Отражение Java - влияние setAccessible (true)
Я использую некоторые аннотации для динамического задания значений полей в классах. Поскольку я хочу сделать это независимо от того, является ли он общедоступным, защищенным или закрытым, я каждый раз вызываю setAccessible(true)
в поле объект перед вызовом метода set()
. Мой вопрос: какое влияние вызывает вызов setAccessible()
на самом поле?
В частности, скажем, это личное поле и этот набор кодовых вызовов setAccessible(true)
. Если какое-то другое место в этом коде было для получения того же поля через отражение, было бы поле уже доступно? Или методы getDeclaredFields()
и getDeclaredField()
возвращают новые экземпляры объекта Field каждый раз?
Я предполагаю, что другой способ задать вопрос, если я назову setAccessible(true)
, насколько важно вернуть его к исходному значению после того, как я закончил?
Ответы
Ответ 1
Почему бы вам не попробовать сами: -)
public class FieldAccessible {
public static class MyClass {
private String theField;
}
public static void main(String[] args) throws Exception {
MyClass myClass = new MyClass();
Field field1 = myClass.getClass().getDeclaredField("theField");
field1.setAccessible(true);
System.out.println(field1.get(myClass));
Field field2 = myClass.getClass().getDeclaredField("theField");
System.out.println(field2.get(myClass));
}
}
Итак, чтобы ответить на ваш вопрос: с помощью setAccessible()
вы изменяете поведение AccessibleObject
, т.е. экземпляр Field
, но не фактическое поле класса. Здесь документация (выдержка):
Значение true
означает, что отраженный объект должен подавлять проверку доступа к языку Java, когда он используется
Ответ 2
Метод getDeclaredField
должен возвращать новый объект каждый раз, именно потому, что этот объект имеет изменяемый accessible
флаг. Поэтому не нужно reset флаг. Вы можете найти полную информацию в этом сообщении в блоге.
Ответ 3
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class PrivateVariableAcc {
public static void main(String[] args) throws Exception {
PrivateVarTest myClass = new PrivateVarTest();
Field field1 = myClass.getClass().getDeclaredField("a");
field1.setAccessible(true);
System.out.println("This is access the private field-"
+ field1.get(myClass));
Method mm = myClass.getClass().getDeclaredMethod("getA");
mm.setAccessible(true);
System.out.println("This is calling the private method-"
+ mm.invoke(myClass, null));
}
}