public interface MethodHandleInfo
通过将直接方法句柄分解为其组成的符号部分而获得的符号引用。要破解直接方法句柄,请调用
Lookup.revealDirect 。
直接方法句柄
direct method handle 表示没有任何干预参数绑定或其他转换的方法、构造函数或字段。直接方法句柄引用的方法、构造函数或字段称为其 underlying member 。可以通过以下任何方式获得直接方法句柄:- 通过对
CONSTANT_MethodHandle常量执行ldc指令。 (请参阅 Java 虚拟机规范,4.4.8 和 5.4.3 部分。) - 通过调用 查找工厂方法 之一,例如
Lookup.findVirtual,将符号引用解析为方法句柄。符号引用由类、名称字符串和类型组成。 - 通过调用工厂方法
Lookup.unreflect或Lookup.unreflectSpecial将一个Method转换成一个方法句柄。 - 通过调用工厂方法
Lookup.unreflectConstructor将一个Constructor转换成一个方法句柄。 - 通过调用工厂方法
Lookup.unreflectGetter或Lookup.unreflectSetter将一个Field转换为方法句柄。
破解限制
给定一个合适的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 |
class 或 interface |
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 |
class 或 interface |
static T m(A*); |
(T) C.m(arg*); |
7 |
REF_invokeSpecial |
class 或 interface |
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
-
字段摘要
字段修饰符和类型Field描述static final int上表 中定义的直接方法句柄引用类型。static final int上表 中定义的直接方法句柄引用类型。static final int上表 中定义的直接方法句柄引用类型。static final int上表 中定义的直接方法句柄引用类型。static final int上表 中定义的直接方法句柄引用类型。static final int上表 中定义的直接方法句柄引用类型。static final int上表 中定义的直接方法句柄引用类型。static final int上表 中定义的直接方法句柄引用类型。static final int上表 中定义的直接方法句柄引用类型。 -
方法总结
修饰符和类型方法描述Class<?>返回定义破解方法句柄的底层成员的类。返回破解符号引用的标称类型,表示为方法类型。int返回基础成员的访问修饰符。getName()返回破解方法句柄的底层成员的名称。int返回破解方法句柄的引用种类,进而判断方法句柄的底层成员是构造方法、方法还是字段。default boolean确定基础成员是可变元数方法还是构造方法。static StringreferenceKindToString(int referenceKind) 返回给定引用种类的描述性名称,如 上表 中所定义。<T extends Member>
TreflectAs(Class<T> expected, MethodHandles.Lookup lookup) 将基础成员反映为方法、构造方法或字段对象。static StringtoString(int kind, Class<?> defc, String name, MethodType type) 给定其符号引用的四个部分,返回MethodHandleInfo的字符串表示形式。
-
字段详细信息
-
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
将基础成员反映为方法、构造函数或字段对象。如果基础成员是公共的,则它反映为getMethod、getConstructor或getField。否则,它就像被getDeclaredMethod、getDeclaredConstructor或getDeclaredField反映一样。给定的查找对象必须可以访问基础成员。- 类型参数:
T- 所需的结果类型,Member或子类型- 参数:
expected- 表示所需结果类型的类对象Tlookup- 创建此 MethodHandleInfo 的查找对象,或具有同等访问权限的查找对象- 返回:
- 对方法、构造方法或字段对象的引用
- 抛出:
ClassCastException- 如果成员不是预期类型NullPointerException- 如果任一参数是nullIllegalArgumentException- 如果给定的查找对象无法访问底层成员
-
getModifiers
int getModifiers()返回基础成员的访问修饰符。- 返回:
- 基础成员的 Java 语言修饰符,如果无法访问该成员,则为 -1
- 参见:
-
isVarArgs
default boolean isVarArgs()确定基础成员是可变元数方法还是构造方法。这些成员由作为可变参数收集器的方法句柄表示。- 实现要求:
-
这产生的结果等同于:
getReferenceKind() >= REF_invokeVirtual && Modifier.isTransient(getModifiers()) - 返回:
true当且仅当底层成员声明为变量 arity 时。
-
referenceKindToString
返回给定引用种类的描述性名称,如 上表 中所定义。省略了常规前缀“REF_”。- 参数:
referenceKind- 用于访问类成员的一种引用的整数代码- 返回:
-
大小写混合的字符串,例如
"getField" - 抛出:
IllegalArgumentException- 如果参数不是有效的 参考种类编号
-
toString
给定其符号引用的四个部分,返回MethodHandleInfo的字符串表示形式。这被定义为"RK C.N:MT"的形式,其中RK是kind的 参考种类字符串,C是defc的 name,N是name,MT是type。这四个值可以从MethodHandleInfo对象的参考类、声明类、成员名字和方法类型获得。- 实现要求:
-
这产生的结果等同于:
String.format("%s %s.%s:%s", referenceKindToString(kind), defc.getName(), name, type) - 参数:
kind- 符号引用的 参考类 部分defc- 符号引用的 声明类 部分name- 符号引用的 成员名字 部分type- 符号引用的 方法类型 部分- 返回:
"RK C.N:MT"形式的字符串- 抛出:
IllegalArgumentException- 如果第一个参数不是有效的 参考种类编号NullPointerException- 如果任何引用参数是null
-