Java 리플렉션 - set Accessible(true)의 영향
주석을 사용하여 클래스의 필드 값을 동적으로 설정합니다.퍼블릭, 프로텍트, 프라이빗을 불문하고 이 작업을 하고 싶기 때문에 저는 콜링입니다.setAccessible(true)
[ Field ]오브젝트에서는 항상set()
방법.제 질문은 이 시스템이 어떤 영향을 미치는지입니다.setAccessible()
필드 자체에 문의할 수 있습니까?
구체적으로는 개인 필드라고 하면, 이 코드 세트입니다.setAccessible(true)
코드의 다른 장소에서 리플렉션으로 같은 필드를 취득하는 경우, 이미 필드에 액세스 할 수 있습니까?또는,getDeclaredFields()
그리고.getDeclaredField()
메서드는 매번 Field 객체의 새 인스턴스를 반환합니까?
질문을 하는 또 다른 방법은 제가 전화를 해서setAccessible(true)
작업을 마친 후 원래 값으로 되돌리는 것이 얼마나 중요합니까?
와 함께setAccessible()
의 동작을 변경합니다.AccessibleObject
(즉,Field
instance. 단, 클래스의 실제 필드는 아닙니다.다음은 매뉴얼(발췌)입니다.
의 값
true
반사된 오브젝트가 Java 언어 액세스컨트롤을 사용할 때 체크하지 않도록 합니다.
실행 가능한 예를 다음에 제시하겠습니다.
public class FieldAccessible {
public static class MyClass {
private String theField;
}
public static void main(String[] args) throws Exception {
MyClass myClass = new MyClass();
Field field1 = myClass.getClass().getDeclaredField("theField");
field1.setAccessible(true);
System.out.println(field1.get(myClass)); // no exception
Field field2 = myClass.getClass().getDeclaredField("theField");
System.out.println(field2.get(myClass)); // IllegalAccessException
}
}
그getDeclaredField
메서드는 매번 새 개체를 반환해야 합니다. 이 개체에 가변 변수가 있기 때문입니다.accessible
플래그를 리셋할 필요가 없습니다.자세한 내용은 이 블로그 투고에서 확인할 수 있습니다.
다른 포스터에서 보듯이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용이며, 이후 버전에서는 백엔드가 변경되어 이 문제가 해결되었습니다.이 전략을 계속 진행하려면 동일한 개념이 적용됩니다.
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class PrivateVariableAcc {
public static void main(String[] args) throws Exception {
PrivateVarTest myClass = new PrivateVarTest();
Field field1 = myClass.getClass().getDeclaredField("a");
field1.setAccessible(true);
System.out.println("This is access the private field-"
+ field1.get(myClass));
Method mm = myClass.getClass().getDeclaredMethod("getA");
mm.setAccessible(true);
System.out.println("This is calling the private method-"
+ mm.invoke(myClass, null));
}
}
언급URL : https://stackoverflow.com/questions/10638826/java-reflection-impact-of-setaccessibletrue
'sourcecode' 카테고리의 다른 글
isset()의 PHP 줄임말? (0) | 2022.10.07 |
---|---|
Python에서 try-except-else를 사용하는 것이 좋은 방법인가요? (0) | 2022.10.07 |
특정 중간 항목을 선택한 MySQL 중첩 집계 쿼리 (0) | 2022.09.26 |
Javascript - 다른 어레이를 기준으로 배열 정렬 (0) | 2022.09.26 |
int 열에 UNIX 타임스탬프를 저장하는 방법을 선택하십시오. (0) | 2022.09.26 |