Отражение 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));
    }

}