다른 포스터에서 지적했듯이은의 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 용이며 향후 버전은이를 중단하는 백엔드를 변경합니다. 이 전략을 계속 진행하려면 동일한 개념이 여전히 적용됩니다.