ตามที่ผู้โพสต์อื่นระบุไว้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 เวอร์ชันในอนาคตจะเปลี่ยนแบ็กเอนด์ซึ่งจะทำลายสิ่งนี้ แนวคิดเดียวกันนี้ยังคงใช้ได้อยู่แม้ว่าคุณจะต้องการดำเนินกลยุทธ์นี้ต่อไป