public class LambdaMetafactory extends Object
方法来促进,通过代表团实现一个或多个接口所提供的简单的“函数对象”的创建MethodHandle
,可能适应类型和参数局部评价。 这些方法通常用作invokedynamic
调用站点的引导方法 ,以支持Java编程语言的lambda表达式和方法引用表达式功能。
对提供的MethodHandle
指定行为的间接访问按顺序进行三个阶段:
CallSite
,其目标可以用于创建合适的功能对象。 链接可能涉及动态加载实现目标接口的新类。 CallSite
可以被认为是功能对象的“工厂”,因此这些连接方法被称为“元件”。 CallSite
的目标时,通常通过invokedynamic
调用站点生成一个函数对象,就会发生捕获 。 对于单个工厂CallSite
可能会发生多次。 Capture可能涉及分配一个新的函数对象,或者可能返回一个现有的函数对象。 行为MethodHandle
可能具有超出指定接口方法的附加参数; 这些被称为捕获的参数 ,它们必须作为CallSite
目标的参数提供,并且可能早于行为MethodHandle
。 在联动期间确定捕获的参数及其类型的数量。 MethodHandle
引用的方法使用捕获的参数和调用时提供的任何其他参数调用,就像MethodHandle.invoke(Object...)
一样 。 限制在调用时允许的输入或结果集有时是有用的。 例如,当通用接口Predicate<T>
被参数化为Predicate<String>
时,输入必须是String
,即使实现方法允许任何Object
。 在链接时,额外的MethodType
参数描述了“实例化”方法类型; 在调用时,根据这个MethodType
检查参数和最终结果。
该类提供两种形式的联动方法:使用优化协议的标准版本( metafactory(MethodHandles.Lookup, String, MethodType, MethodType, MethodHandle, MethodType)
)和备用版本altMetafactory(MethodHandles.Lookup, String, MethodType, Object...)
)。 备用版本是标准版本的泛化,通过标志和附加参数提供对生成的函数对象的行为的附加控制。 备用版本增加了管理功能对象的以下属性的功能:
FLAG_BRIDGES
表示的附加列表MethodType
旨意提供,其中的每一个将被生成的函数对象来实现。 这些方法将共享相同的名称和实例化的类型。 FLAG_MARKERS
表示将被提供的额外的接口的列表,其中的每一个应当由所得到的函数对象来实现。 FLAG_SERIALIZABLE
来表示功能对象应该可串行化。 可串行化的函数对象将使用SerializedLambda类的SerializedLambda
,它们需要捕获类的额外帮助( MethodHandles.Lookup
参数caller
的类); 详见SerializedLambda
。 假设链接参数如下:
invokedType
(描述CallSite
签名)具有类型(D1..Dk)和返回类型Rd的K个参数; samMethodType
(描述实现的方法类型)具有N个参数,类型(U1..Un)和返回类型Ru; implMethod
( MethodHandle
实现的MethodHandle具有M个参数,类型(A1..Am)和返回类型Ra(如果该方法描述一个实例方法,此方法句柄的方法类型已经包含与接收器对应的额外的第一个参数) ; instantiatedMethodType
(允许调用限制)具有N个参数,类型(T1..Tn)和返回类型Rt。 那么以下链接不变量必须保持:
implMethod
是一个直接的方法句柄 samMethodType
和instantiatedMethodType
具有相同的instantiatedMethodType
N,对于i = 1..N,Ti和Ui是相同类型,或Ti和Ui都是参考类型,Ti是Ui的亚型 此外,在捕获时间,如果implMethod
对应于一个实例方法,并且有任何捕获参数( K > 0
),那么第一个捕获参数(对应于接收者)必须是非空值。
Q类型被认为适应于S,如下所示:
Q S Link-time checks Invocation-time checks Primitive Primitive Q can be converted to S via a primitive widening conversion None Primitive Reference S is a supertype of the Wrapper(Q) Cast from Wrapper(Q) to S Reference Primitive for parameter types: Q is a primitive wrapper and Primitive(Q) can be widened to S实现方法的参数列表和接口方法的参数列表可能有多种不同。 实现方法可能有其他参数来适应lambda表达式捕获的参数; 还可能会因允许的参数调整而产生差异,如铸造,拳击,拆箱和原始拓宽。 (Varargs修改不由metafactories处理;这些调整将被调用者处理。)
Invokedynamic调用站点有两个参数列表:静态参数列表和动态参数列表。 静态参数列表存储在常量池中; 动态参数在捕获时被推送到操作数堆栈上。 引导方法可以访问整个静态参数列表(在这种情况下,包括描述实现方法,目标接口和目标接口方法的信息),以及描述数字和静态类型的方法签名(但不是值)的动态参数和调用动态站点的静态返回类型。
Modifier and Type | Field and Description |
---|---|
static int |
FLAG_BRIDGES
指示lambda对象的备用元素的标志需要额外的桥接方法
|
static int |
FLAG_MARKERS
指示lambda对象的替代元素的标志实现除Serializable之外的其他标记接口
|
static int |
FLAG_SERIALIZABLE
指示lambda对象的替代元素的标志必须是可序列化的
|
Constructor and Description |
---|
LambdaMetafactory() |
Modifier and Type | Method and Description |
---|---|
static CallSite |
altMetafactory(MethodHandles.Lookup caller, String invokedName, MethodType invokedType, Object... args)
通过委派给所提供的 MethodHandle ,在适当的类型适应和参数的部分评估之后,便于创建简单的“功能对象”,实现一个或多个接口。
|
static CallSite |
metafactory(MethodHandles.Lookup caller, String invokedName, MethodType invokedType, MethodType samMethodType, MethodHandle implMethod, MethodType instantiatedMethodType)
通过委派给提供的 MethodHandle ,在适当的类型适应和参数的部分评估后,便于创建实现一个或多个接口的简单“功能对象”。
|
public static final int FLAG_SERIALIZABLE
public static final int FLAG_MARKERS
public static final int FLAG_BRIDGES
public static CallSite metafactory(MethodHandles.Lookup caller, String invokedName, MethodType invokedType, MethodType samMethodType, MethodHandle implMethod, MethodType instantiatedMethodType) throws LambdaConversionException
MethodHandle
,经过适当的适应型和参数部分的评价。
通常用作invokedynamic
调用站点的引导方法 ,以支持Java编程语言的lambda表达式和方法引用表达式功能。
这是标准的流线型meta factory; 额外的灵活性由altMetafactory(MethodHandles.Lookup, String, MethodType, Object...)
提供。 提供这种方法的一般描述above
。
当调用从此方法返回的CallSite
的目标时,生成的函数对象是实现由invokedType的返回类型命名的接口的类的invokedType
,声明一个名称由invokedName
给出的invokedName
,由samMethodType给出的samMethodType
。 它也可以从覆盖其他方法Object
。
caller
- 表示具有调用者的辅助权限的查找上下文。
当与invokedynamic
一起使用时,VM由VM自动堆叠。
invokedName
- 要实现的方法的名称。
当与invokedynamic
一起使用时,它由NameAndType
的InvokeDynamic
提供,并由VM自动堆叠。
invokedType
- invokedType
的预期CallSite
。
参数类型表示捕获变量的类型;
返回类型是要实现的接口。
当与invokedynamic
一起使用时,它由NameAndType
结构的InvokeDynamic
提供,并由VM自动堆叠。
在实现方法是实例方法且该签名具有任何参数的情况下,调用签名中的第一个参数必须对应于接收方。
samMethodType
- 由函数对象执行的方法的签名和返回类型。
implMethod
- 一个直接方法句柄,用于描述在调用时应该被调用的实现方法(在参数类型,返回类型以及调用参数前面带有捕获参数的适当适配)。
instantiatedMethodType
- 在调用时动态执行的签名和返回类型。
这可能与samMethodType
相同,或者可能是它的专业化。
invokedType
LambdaConversionException
- 如果违反了所描述的任何链接不变量above
public static CallSite altMetafactory(MethodHandles.Lookup caller, String invokedName, MethodType invokedType, Object... args) throws LambdaConversionException
MethodHandle
,经过适当的适应型和参数部分的评价。
通常用作invokedynamic
调用站点的引导方法 ,以支持Java编程语言的lambda表达式和方法引用表达式功能。
这是一般的,更灵活的meta factory; 简化的版本由altMetafactory(MethodHandles.Lookup, String, MethodType, Object...)
提供。 此方法的行为的一般描述提供above
。
该方法的参数列表中包括三个固定的参数,对应于由VM自举方法在一个自动堆叠在参数invokedynamic
调用,和Object[]
包含额外参数的参数。 该方法的声明参数列表是:
CallSite altMetafactory(MethodHandles.Lookup caller, String invokedName, MethodType invokedType, Object... args)
但它的行为就好像参数列表如下所示:
CallSite altMetafactory(MethodHandles.Lookup caller, String invokedName, MethodType invokedType, MethodType samMethodType, MethodHandle implMethod, MethodType instantiatedMethodType, int flags, int markerInterfaceCount, // IF flags has MARKERS set Class... markerInterfaces, // IF flags has MARKERS set int bridgeCount, // IF flags has BRIDGES set MethodType... bridges // IF flags has BRIDGES set )
出现在参数列表参数metafactory(MethodHandles.Lookup, String, MethodType, MethodType, MethodHandle, MethodType)
具有相同规格的这种方法。 附加论据解释如下:
flags
表示附加选项; 这是所需标志的按位OR。 定义的标志为FLAG_BRIDGES
, FLAG_MARKERS
和FLAG_SERIALIZABLE
。 markerInterfaceCount
是函数对象应该实现的附加接口的数量,当且仅当设置了FLAG_MARKERS
标志时才会出现。 markerInterfaces
是要实现的附加接口的可变长度列表,其长度等于markerInterfaceCount
,并且当且仅当设置了FLAG_MARKERS
标志时才存在。 bridgeCount
是函数对象应该实现的附加方法签名的数量,当且仅当设置了FLAG_BRIDGES
标志时才会出现。 bridges
是要实现的附加方法签名的可变长度列表,其长度等于bridgeCount
,并且当且仅当设置了FLAG_BRIDGES
标志时才存在。 每个由markerInterfaces
命名的markerInterfaces
受到与Rd相同的Rd
,返回类型为invokedType
,如above
所述 。 每个MethodType
由名为bridges
受到相同的限制samMethodType
,如所描述的above
。
当在flags中设置flags
时,函数对象将实现Serializable
,并且具有writeReplace
方法返回适当的SerializedLambda
。 caller
类必须具有相应的$deserializeLambda$
方法,如SerializedLambda
所述 。
当调用从此方法返回的CallSite
的目标时,生成的函数对象是具有以下属性的类的实例:
invokedType
和由markerInterfaces
命名的任何markerInterfaces
invokedName
,并给出签名samMethodType
给出的和额外的签名bridges
Object
中的方法,并且可以实现与序列化相关的方法。 caller
- 表示具有调用方访问权限的查找上下文。
当与invokedynamic
一起使用时,VM将自动堆叠。
invokedName
- 要实现的方法的名称。
当与invokedynamic
一起使用时,由NameAndType
的InvokeDynamic
提供,并由VM自动堆叠。
invokedType
- invokedType
的预期CallSite
。
参数类型表示捕获变量的类型;
返回类型是要实现的接口。
当与invokedynamic
一起使用时,由NameAndType
的InvokeDynamic
提供,并由VM自动堆叠。
在实现方法是实例方法且该签名具有任何参数的情况下,调用签名中的第一个参数必须对应于接收方。
args
-一个
Object[]
含有所需参数数组
samMethodType
,
implMethod
,
instantiatedMethodType
,
flags
,和任何任选的参数,如所描述
altMetafactory(MethodHandles.Lookup, String, MethodType, Object...)
以上}
invokedType
LambdaConversionException
-如果有任何的联系不变量描述above
受到侵犯