MethodHandleInfo — 직접 메서드 핸들을 깨서 얻는 기호 참조
MethodHandleInfo — 직접 메서드 핸들을 깨서 얻는 기호 참조
MethodHandleInfo는 직접 메서드 핸들(direct method handle)을 그것을 구성하는 기호적 부분들로 크래킹(cracking) 해서 얻은 기호 참조(symbolic reference)예요. 직접 메서드 핸들을 크래킹하려면 Lookup.revealDirect를 호출하면 돼요.
본문
직접 메서드 핸들(Direct Method Handles)
직접 메서드 핸들은 중간에 인자 바인딩이나 다른 변환이 없는 상태의 메서드·생성자·필드를 나타내요. 직접 메서드 핸들이 가리키는 메서드·생성자·필드를 그 밑바탕 멤버(underlying member) 라고 불러요. 직접 메서드 핸들은 다음과 같은 방법으로 얻을 수 있어요.
CONSTANT_MethodHandle상수에 대한ldc명령어를 실행하기Lookup.findVirtual같은 Lookup 팩토리 메서드를 호출해 기호 참조를 메서드 핸들로 해석하기. 기호 참조는 클래스·이름 문자열·타입으로 구성돼요.Lookup.unreflect·Lookup.unreflectSpecial을 호출해Method를 메서드 핸들로 변환하기Lookup.unreflectConstructor를 호출해Constructor를 메서드 핸들로 변환하기Lookup.unreflectGetter·Lookup.unreflectSetter를 호출해Field를 메서드 핸들로 변환하기
크래킹 제한(Restrictions on Cracking)
적절한 Lookup 객체가 주어지면, 어떤 직접 메서드 핸들도 크래킹해 밑바탕 메서드·생성자·필드의 기호 참조를 복구할 수 있어요. 크래킹은 대상 메서드 핸들을 만든 것과 동등한 Lookup 객체로 해야 하거나, 동등한 메서드 핸들을 재생성하기에 충분한 접근 권한을 가진 Lookup으로 해야 해요.
밑바탕 메서드가 caller-sensitive하면, 직접 메서드 핸들은 그걸 만드는 데 사용된 lookup 객체의 lookup class인 특정 호출자 클래스에 "바인딩" 됩니다. 다른 lookup class로 이 메서드 핸들을 크래킹하면, 밑바탕 메서드가 public이어도(예: Class.forName) 실패해요. 이런 lookup 객체 일치 요구는, 예상치 못한 스코프의 기호 정보(또는 호출자 바인딩)로 메서드 핸들을 잘못 드러내는 것을 신뢰할 수 있는 프로그램에 대해 "빠른 실패(fast fail)" 동작을 제공해요. 이 제한을 우회하려면 MethodHandles.reflectAs(Class<T>, MethodHandle)을 사용하면 돼요.
참조 종류(Reference kinds)
Lookup 팩토리 메서드들 .. (메서드 핸들이 어떤 종류의 멤버를 가리키는지, REF_getField·REF_invokeVirtual 같은 참조 종류 상수로 나타냄)
주요 메서드
int getReferenceKind()— 밑바탕 멤버의 참조 종류를 반환해요.Class<?> getDeclaringClass()— 밑바탕 멤버를 선언한 클래스를 반환해요.String getName()— 밑바탕 멤버의 이름을 반환해요.MethodType getMethodType()— 밑바탕 멤버의 (메서드 타입으로서의) 타입 설명자를 반환해요.int getModifiers()— 밑바탕 멤버의 자바 언어 접근 제어자를 반환해요.