Như các áp phích khác đã chỉ ra, setAccessible
chỉ áp dụng cho phiên bản đó của bạn java.lang.reflect.Field
, vì vậy không cần đặt khả năng truy cập trở lại trạng thái ban đầu.
Tuy nhiên...
Nếu bạn muốn cuộc gọi của mình field.setAccessible(true)
được liên tục, bạn cần sử dụng các phương pháp cơ bản trong java.lang.Class
và java.lang.reflect.Field
. Các phương thức công khai gửi cho bạn các bản sao của Field
phiên bản, vì vậy nó sẽ "quên" sau mỗi lần bạn làm điều gì đó như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();
}
}
}
Cập nhật : Việc triển khai này dành cho Java 8, các phiên bản trong tương lai sẽ thay đổi chương trình phụ trợ làm hỏng điều này. Tuy nhiên, khái niệm tương tự vẫn được áp dụng nếu bạn thực sự muốn tiếp tục chiến lược này.