Як вказували інші афіші, setAccessibleзастосовний лише до цього примірника вашого java.lang.reflect.Field, тому повернення доступності до початкового стану не потрібно.
Однак ...
Якщо ви хочете, щоб ваші дзвінки field.setAccessible(true)були постійними, вам потрібно використовувати основні методи в java.lang.Classі java.lang.reflect.Field. Громадськість облицювальних методів відправити вам копію цього Fieldпримірника, так що «забуває» після того, як кожен раз , коли ви робите що - щось на зразокclass.getField(name)
import java.lang.reflect.*;
import sun.reflect.FieldAccessor;
public class Reflect {
private static Method privateGetDeclaredFields;
private static Method getFieldAccessor;
public static Field[] fields(Class<?> clazz) throws Exception {
return (Field[]) privateGetDeclaredFields.invoke(clazz, false);
}
public static <T> T get(Object instance, Field field) throws Exception {
return ((FieldAccessor) getFieldAccessor.invoke(field, instance)).get(instance);
}
public static void set(Object instance, Field field, Object value) throws Exception {
((FieldAccessor) getFieldAccessor.invoke(field, instance)).set(instance, value);
}
static {
try {
// These are used to access the direct Field instances instead of the copies you normally get through #getDeclaredFields.
privateGetDeclaredFields = Class.class.getDeclaredMethod("privateGetDeclaredFields", boolean.class);
privateGetDeclaredFields.setAccessible(true);
getFieldAccessor = Field.class.getDeclaredMethod("getFieldAccessor", Object.class);
getFieldAccessor.setAccessible(true);
} catch (Exception e) {
// Should only occur if the internals change.
e.printStackTrace();
}
}
}
Оновлення : ця реалізація призначена для Java 8, майбутні версії змінюють допоміжний сервер, який порушує цю проблему. Ця ж концепція досі застосовується, хоча ви дійсно бажаєте продовжувати цю стратегію.