模块 java.base

接口 MethodHandleInfo


public interface MethodHandleInfo
通过将直接方法句柄分解为其组成的符号部分而获得的符号引用。要破解直接方法句柄,请调用 Lookup.revealDirect

直接方法句柄

direct method handle 表示没有任何干预参数绑定或其他转换的方法、构造函数或字段。直接方法句柄引用的方法、构造函数或字段称为其 underlying member 。可以通过以下任何方式获得直接方法句柄:

破解限制

给定一个合适的 Lookup 对象,可以破解任何直接方法句柄以恢复底层方法、构造函数或字段的符号引用。破解必须通过一个 Lookup 对象来完成,该对象等同于创建目标方法句柄的对象,或者具有足够的访问权限来重新创建等效方法句柄的对象。

如果底层方法是 来电敏感 ,则直接方法句柄将“绑定”到特定的调用者类,即用于创建它的查找对象的 查找类。使用不同的查找类破解此方法句柄将失败,即使底层方法是公共的(如 Class.forName )。

查找对象匹配的要求为程序提供了“快速失败”行为,否则这些程序可能会相信方法句柄的错误揭示以及来自意外范围的符号信息(或调用者绑定)。使用 MethodHandles.reflectAs(java.lang.Class<T>, java.lang.invoke.MethodHandle) 覆盖此限制。

参考种

查找工厂方法 对应于方法、构造函数和字段的所有主要用例。这些用例可以使用小整数来区分,如下所示:
参考种类
参考类 描述性名称 范围 成员 行为
1 REF_getField class FT f; (T) this.f;
2 REF_getStatic classinterface static
FT f;
(T) C.f;
3 REF_putField class FT f; this.f = x;
4 REF_putStatic class static
FT f;
C.f = arg;
5 REF_invokeVirtual class T m(A*); (T) this.m(arg*);
6 REF_invokeStatic classinterface static
T m(A*);
(T) C.m(arg*);
7 REF_invokeSpecial classinterface T m(A*); (T) super.m(arg*);
8 REF_newInvokeSpecial class C(A*); new C(arg*);
9 REF_invokeInterface interface T m(A*); (T) this.m(arg*);
自从:
1.8
  • 字段详细信息

    • REF_getField

      static final int REF_getField
      上表 中定义的直接方法句柄引用类型。
      参见:
    • REF_getStatic

      static final int REF_getStatic
      上表 中定义的直接方法句柄引用类型。
      参见:
    • REF_putField

      static final int REF_putField
      上表 中定义的直接方法句柄引用类型。
      参见:
    • REF_putStatic

      static final int REF_putStatic
      上表 中定义的直接方法句柄引用类型。
      参见:
    • REF_invokeVirtual

      static final int REF_invokeVirtual
      上表 中定义的直接方法句柄引用类型。
      参见:
    • REF_invokeStatic

      static final int REF_invokeStatic
      上表 中定义的直接方法句柄引用类型。
      参见:
    • REF_invokeSpecial

      static final int REF_invokeSpecial
      上表 中定义的直接方法句柄引用类型。
      参见:
    • REF_newInvokeSpecial

      static final int REF_newInvokeSpecial
      上表 中定义的直接方法句柄引用类型。
      参见:
    • REF_invokeInterface

      static final int REF_invokeInterface
      上表 中定义的直接方法句柄引用类型。
      参见:
  • 方法详情

    • getReferenceKind

      int getReferenceKind()
      返回破解方法句柄的引用种类,进而判断方法句柄的底层成员是构造函数、方法还是字段。有关定义,请参阅 上表
      返回:
      用于访问基础成员的引用类型的整数代码
    • getDeclaringClass

      Class <?> getDeclaringClass()
      返回定义破解方法句柄的底层成员的类。
      返回:
      底层成员的声明类
    • getName

      String  getName()
      返回破解方法句柄的底层成员的名称。这是 "<init>" 如果基础成员是一个构造函数,否则它是一个简单的方法名称或字段名称。
      返回:
      基础成员的简单名称
    • getMethodType

      MethodType  getMethodType()
      返回破解符号引用的标称类型,表示为方法类型。如果引用是对构造函数的引用,则返回类型将为 void 。如果是给非静态方法,方法类型不会提到this参数。如果是对一个字段,请求的访问是读取该字段,方法类型将没有参数,返回字段类型。如果是一个字段,并且请求的访问是写入该字段,方法类型将有一个字段类型的参数并返回 void

      请注意,原始直接方法句柄可能包含前导 this 参数,或者(在构造函数的情况下)将用构造的类替换 void 返回类型。标称类型不包含任何 this 参数,并且(在构造函数的情况下)将返回 void

      返回:
      底层成员的类型,表示为方法类型
    • reflectAs

      <T extends Member > T reflectAs(Class <T> expected, MethodHandles.Lookup  lookup)
      将基础成员反映为方法、构造函数或字段对象。如果基础成员是公共的,则它反映为 getMethodgetConstructorgetField 。否则,它就像被 getDeclaredMethodgetDeclaredConstructorgetDeclaredField 反映一样。给定的查找对象必须可以访问基础成员。
      类型参数:
      T - 所需的结果类型,Member 或子类型
      参数:
      expected - 表示所需结果类型的类对象 T
      lookup - 创建此 MethodHandleInfo 的查找对象,或具有同等访问权限的查找对象
      返回:
      对方法、构造方法或字段对象的引用
      抛出:
      ClassCastException - 如果成员不是预期类型
      NullPointerException - 如果任一参数是 null
      IllegalArgumentException - 如果给定的查找对象无法访问底层成员
    • getModifiers

      int getModifiers()
      返回基础成员的访问修饰符。
      返回:
      基础成员的 Java 语言修饰符,如果无法访问该成员,则为 -1
      参见:
    • isVarArgs

      default boolean isVarArgs()
      确定基础成员是可变元数方法还是构造方法。这些成员由作为可变参数收集器的方法句柄表示。
      实现要求:
      这产生的结果等同于:
      
         getReferenceKind() >= REF_invokeVirtual && Modifier.isTransient(getModifiers())
        
      返回:
      true 当且仅当底层成员声明为变量 arity 时。
    • referenceKindToString

      static String  referenceKindToString(int referenceKind)
      返回给定引用种类的描述性名称,如 上表 中所定义。省略了常规前缀“REF_”。
      参数:
      referenceKind - 用于访问类成员的一种引用的整数代码
      返回:
      大小写混合的字符串,例如 "getField"
      抛出:
      IllegalArgumentException - 如果参数不是有效的 参考种类编号
    • toString

      static String  toString(int kind, Class <?> defc, String  name, MethodType  type)
      给定其符号引用的四个部分,返回 MethodHandleInfo 的字符串表示形式。这被定义为 "RK C.N:MT" 的形式,其中 RKkind参考种类字符串CdefcnameNnameMTtype。这四个值可以从MethodHandleInfo对象的参考类声明类成员名字方法类型获得。
      实现要求:
      这产生的结果等同于:
      
         String.format("%s %s.%s:%s", referenceKindToString(kind), defc.getName(), name, type)
        
      参数:
      kind - 符号引用的 参考类 部分
      defc - 符号引用的 声明类 部分
      name - 符号引用的 成员名字 部分
      type - 符号引用的 方法类型 部分
      返回:
      "RK C.N:MT" 形式的字符串
      抛出:
      IllegalArgumentException - 如果第一个参数不是有效的 参考种类编号
      NullPointerException - 如果任何引用参数是 null