जैसा कि अन्य पोस्टरों ने संकेत दिया है, 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();
}
}
}
अद्यतन : यह कार्यान्वयन जावा 8 के लिए है, भविष्य के संस्करण बैकएंड को बदलते हैं जो इसे तोड़ता है। एक ही अवधारणा अभी भी लागू होती है, हालांकि आपको वास्तव में इस रणनीति को जारी रखना चाहिए।