MethodHandleInfo — 직접 메서드 핸들을 깨서 얻는 기호 참조

MethodHandleInfo — 직접 메서드 핸들을 깨서 얻는 기호 참조

MethodHandleInfo직접 메서드 핸들(direct method handle)을 그것을 구성하는 기호적 부분들로 크래킹(cracking) 해서 얻은 기호 참조(symbolic reference)예요. 직접 메서드 핸들을 크래킹하려면 Lookup.revealDirect를 호출하면 돼요.

출처: Java API Reference

본문

직접 메서드 핸들(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() — 밑바탕 멤버의 자바 언어 접근 제어자를 반환해요.

더 알아보기 (Learn more)