public interface MethodHandleInfo
通过将直接方法句柄破解为其组成符号部分而获得的符号引用。要破解直接方法句柄,请调用
Lookup.revealDirect。
直接方法句柄
一个直接方法句柄表示一个方法、构造函数或字段,没有任何中间参数绑定或其他转换。直接方法句柄引用的方法、构造函数或字段称为其基础成员。可以通过以下任何方式获取直接方法句柄:- 通过在
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对象等效的Lookup对象进行破解,或者具有足够的访问权限来重新创建等效的方法句柄。
如果基础方法是调用者敏感的,则直接方法句柄将已经“绑定”到特定的调用者类,即用于创建它的查找对象的查找类。使用不同的查找类破解此方法句柄将失败,即使基础方法是公共的(如Class.forName)。
查找对象匹配的要求为可能信任错误的方法句柄的符号信息(或调用者绑定)从意外范围泄露的程序提供了“快速失败”行为。使用MethodHandles.reflectAs(java.lang.Class<T>, java.lang.invoke.MethodHandle)来覆盖此限制。
引用种类
查找工厂方法对应于方法、构造函数和字段的所有主要用例。可以使用以下小整数区分这些用例:| 引用种类 | 描述名称 | 范围 | 成员 | 行为 |
|---|---|---|---|---|
1 |
REF_getField |
类 |
FT f; |
(T) this.f; |
2 |
REF_getStatic |
类或接口 |
staticFT f; |
(T) C.f; |
3 |
REF_putField |
类 |
FT f; |
this.f = x; |
4 |
REF_putStatic |
类 |
staticFT f; |
C.f = arg; |
5 |
REF_invokeVirtual |
类 |
T m(A*); |
(T) this.m(arg*); |
6 |
REF_invokeStatic |
类或接口 |
staticT m(A*); |
(T) C.m(arg*); |
7 |
REF_invokeSpecial |
类或接口 |
T m(A*); |
(T) super.m(arg*); |
8 |
REF_newInvokeSpecial |
类 |
C(A*); |
new C(arg*); |
9 |
REF_invokeInterface |
接口 |
T m(A*); |
(T) this.m(arg*); |
- 自:
- 1.8
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic 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一个直接方法句柄引用种类,如上表所定义。 -
Method Summary
Modifier and TypeMethodDescriptionClass<?> 返回破解方法句柄的基础成员所定义的类。返回破解符号引用的名义类型,表示为方法类型。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的字符串表示,给定其符号引用的四个部分。
-
Field Details
-
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直接方法句柄引用类型,如上表中定义的。- 参见:
-
-
Method Details
-
getReferenceKind
int getReferenceKind()返回破解方法句柄的引用类型,进而确定方法句柄的基础成员是构造函数、方法还是字段。请参阅上表中的定义。- 返回:
- 用于访问基础成员的引用类型的整数代码
-
getDeclaringClass
Class<?> getDeclaringClass()返回破解方法句柄的基础成员所在的类。- 返回:
- 基础成员的声明类
-
getName
String getName()返回破解方法句柄的基础成员的名称。如果基础成员是构造函数,则为"",否则为简单方法名或字段名。 - 返回:
- 基础成员的简单名称
-
getMethodType
MethodType getMethodType()返回破解符号引用的名义类型,表示为方法类型。如果引用是构造函数,则返回类型将为void。如果是非静态方法,则方法类型不会提及this参数。如果是字段且请求访问是读取字段,则方法类型将没有参数并返回字段类型。如果是字段且请求访问是写入字段,则方法类型将有一个字段类型的参数并返回void。请注意,原始直接方法句柄可能包括一个前导
this参数,或者(在构造函数的情况下)将void返回类型替换为构造的类。名义类型不包括任何this参数,并且(在构造函数的情况下)将返回void。- 返回:
- 表示基础成员类型的方法类型
-
reflectAs
将基础成员反映为方法、构造函数或字段对象。如果基础成员是公共的,则将其反映为getMethod、getConstructor或getField。否则,将其反映为getDeclaredMethod、getDeclaredConstructor或getDeclaredField。基础成员必须对给定查找对象可访问。- 类型参数:
-
T- 结果的期望类型,可以是Member或其子类型 - 参数:
-
expected- 表示期望结果类型T的类对象 -
lookup- 创建此MethodHandleInfo的查找对象,或具有等效访问权限的对象 - 返回:
- 方法、构造函数或字段对象的引用
- 异常:
-
ClassCastException- 如果成员不是期望的类型 -
NullPointerException- 如果任一参数为null -
IllegalArgumentException- 如果基础成员对给定查找对象不可访问
-
getModifiers
int getModifiers()返回基础成员的访问修饰符。- 返回:
- 基础成员的Java语言修饰符,如果成员无法访问,则为-1
- 参见:
-
isVarArgs
default boolean isVarArgs()确定基础成员是否为可变参数方法或构造函数。这些成员由作为varargs收集器的方法句柄表示。- 实现要求:
-
这会产生等效于:
getReferenceKind() >= REF_invokeVirtual && Modifier.isTransient(getModifiers()) - 返回:
-
如果基础成员声明为可变参数,则返回
true。
-
referenceKindToString
返回给定引用类型的描述性名称,如上表中定义的。常规前缀"REF_"被省略。- 参数:
-
referenceKind- 用于访问类成员的引用类型的整数代码 - 返回:
-
诸如
"getField"的混合大小写字符串 - 异常:
-
IllegalArgumentException- 如果参数不是有效的引用类型编号
-
toString
给定符号引用的四个部分,返回MethodHandleInfo的字符串表示形式。定义为"RK C.N:MT"的形式,其中RK是kind的引用类型字符串,C是defc的名称,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
-