접근 속성 이나 방법 을 반사 할 때 Accessible 을 true 로 설정 합 니 다.
3798 단어 자바 프로그램의 151 가지 제안
Method method =...... ;
//
if({method.isAccessible()){
method-setAccessible(true);
}
//
method.invoke(obj, args);
이 코드 는 이미 습관 적 인 용법 이 되 었 습 니 다.반사 방식 으로 방법 을 집행 할 때 invoke 전에 Accessible 속성 을 검사 해 야 합 니 다.이것 은 좋 은 습관 입 니 다.물론 그래 야 합 니 다.그러나 방법 대상 의 Accessible 속성 은 접근 여 부 를 결정 하 는 것 이 아 닙 니 다.다음 코드 를 보 세 요.
public class Foo {
public final void doStuff() {
System.out.printIn("DoStuff").
}
}
Public 클래스 의 Public 방법 을 정의 합 니 다.이것 은 어떠한 제한 도 없 는 방법 입 니 다.자바 언어 에 대한 이해 에 따라 doStuff 방법 은 모든 클래스 에 접근 할 수 있 습 니 다.우 리 는 클 라 이언 트 클래스 를 만들어 서 이 방법 이 반사 적 으로 실 행 될 수 있 는 지 확인 합 니 다.
public static void main(String[] args) throws Exception {
//
Method ml = Foo.class.getMethod("doStuff");
//
System.out.println("Accessible= "+ml.isAccessible());
//
ml.invoke(new Foo());
}
간단 한 반사 조작 으로 하나의 방법 을 얻 은 후에 방문 할 수 있 는 지 확인 하고 마지막 으로 방법 을 집행 하여 출력 한다.결 과 를 추측 해 보 자.Foo 류 는 Public 이 고 방법 도 Public 이 며 모두 가장 개방 적 인 접근 권한 이기 때문에 Accessible 도 true 와 같 아야 한다.하지만 운행 결 과 는:
Accessible = false
Do Stuff....
왜 Accessible 속성 은 false 와 같 습 니까?그것 도 false 인 데 실행 할 수 있 겠 어 요?이것 은 Accessible 의 속성 은 우리 문법 등급 이 이해 하 는 방문 권한 이 아니 라 더 쉽게 얻 을 수 있 는 지,안전 검 사 를 할 수 있 는 지 를 가리 키 기 때문이다.
우 리 는 동태 적 으로 하나의 유형 이나 방법 이나 집행 방법 을 수정 할 때 자바 안전 시스템 의 제약 을 받는다 는 것 을 알 고 있 습 니 다.안전 한 처 리 는 자원 을 매우 소모 하 는(성능 이 매우 낮 음)이기 때문에 운행 기간 에 실행 할 방법 이나 수정 할 속성 에 대해 Accessible 옵션 을 제공 합 니 다.개발 자가 안전 시스템 의 검 사 를 피 할 지 여 부 를 결정 합 니 다.
원본 코드 를 읽 는 것 은 이해 하 는 가장 좋 은 방법 입 니 다.AccessibleObject 류 의 소스 코드 를 살 펴 보면 기본 접근 제어 검 사 를 취소 하 는 기능 을 제공 합 니 다.우선 isAccessible 방법 을 살 펴 보 세 요.코드 는 다음 과 같 습 니 다.
public class AccessibleObject implements AnnotatedElement {
// :suppressAccessChecks
static final private java, security.Permission ACCESS PERMISSION = new ReflectPermission{"suppresBAcceasChacks");
// , false
boolean override;
//
protected Accessible Object() {}
// ,
public boolean isAccessible() {
return override;
}
AccessibleObject 는 Field,Method,Constructor 의 부모 클래스 로 접근 제어 검 사 를 하지 않 고 빠르게 접근 할 수 있 는 지 여 부 를 결정 합 니 다.AccessibleObject 류 에 서 는 override 변수 로 이 값 을 저장 하지만 구체 적 으로 빠 른 실행 여 부 는 Method 류 의 invoke 방법 에서 결 정 됩 니 다.코드 는 다음 과 같 습 니 다.
public Object invoke(Object obj, Object... args) throws ... {
// , AccessibleObject override
if{!override) {
// ,
if (!Reflection.quickCheckMemberAccess(....) {
Reflection.ensureMemberAcce88
}
//
return methodAccessor.invoke(obj,args);
}
이 코드 를 보면 여러분 은 잘 알 수 있 습 니 다.Accessible 속성 은 안전 검 사 를 해 야 하 는 지 여 부 를 판단 하 는 데 만 사용 되 고 필요 하지 않 으 면 직접 집행 하면 시스템 성능 을 크게 향상 시 킬 수 있 습 니 다(물론 안전 검 사 를 취소 하기 때문에 private 방법 을 실행 하고 private 사유 속성 을 방문 할 수 있 습 니 다).테스트 를 통 해 대량의 반사 상황 에서 Accessible 을 true 로 설정 하면 성능 을 20 배 이상 향상 시 킬 수 있다.
AccessibleObject 의 다른 두 가지 하위 클래스 인 Field 와 Constructor 는 Method 와 비슷 한 상황 입 니 다.Accessible 속성 은 Field 와 Constructor 가 방문 통제 검 사 를 받 는 지 여 부 를 결정 합 니 다.우 리 는 Field 를 설정 하거나 Constructor 를 실행 할 때 Accessible 을 true 로 설정 해 야 합 니 다.이것 은 조작 습관 때 문 만 이 아니 라 우리 시스템 의 성능 을 고려 하고 있 습 니 다.
내 가 이미 습관 이 된 코드 에 대해 서 는 왜 그런 지 많이 생각해 보 세 요.