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 |
类 或接口 |
static FT f; |
(T) C.f; |
3 |
REF_putField |
类 |
FT f; |
this.f = x; |
4 |
REF_putStatic |
类 |
static FT f; |
C.f = arg; |
5 |
REF_invokeVirtual |
类 |
T m(A*); |
(T) this.m(arg*); |
6 |
REF_invokeStatic |
类 或接口 |
static T 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
Modifier 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 String
referenceKindToString
(int referenceKind) 返回给定引用种类的描述名称,如上表所定义。<T extends Member>
TreflectAs
(Class<T> expected, MethodHandles.Lookup lookup) 将基础成员反映为方法、构造函数或字段对象。static String
toString
(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
-