接口 | 描述 |
---|---|
MethodHandleInfo |
一个符号引用的直接方法处理开裂成成分符号部分获得。
|
类 | 描述 |
---|---|
CallSite | |
ConstantCallSite |
一个
ConstantCallSite 是
CallSite 其目标是永久的,而且永远不会改变。
|
LambdaMetafactory |
方法方便简单的“对象”,实现由一个或多个接口,一个代表团提供
MethodHandle 创作,可能在式改编和部分论据评价。
|
MethodHandle |
方法句柄是一个类型化的,直接可执行的引用到一个基本的方法、构造函数、字段或类似的低级操作,具有可选的参数或返回值的转换。
|
MethodHandleProxies |
这类由专门的静态方法,帮助适应方法处理其他JVM类型,如接口。
|
MethodHandles |
这个类完全由操作或返回方法处理的静态方法组成。
|
MethodHandles.Lookup |
查找对象是一个用于创建方法句柄的工厂,当创建需要访问检查时。
|
MethodType |
方法类型表示接受和返回的参数和返回类型的方法处理,或通过方法处理调用方传递的参数和返回类型。
|
MutableCallSite |
一个
MutableCallSite 是一个目标变量的行为像一个普通的领域
CallSite 。
|
SerializedLambda |
序列化形式的lambda表达式。
|
SwitchPoint |
一个
SwitchPoint 是可以发布状态转换到其他线程对象。
|
VolatileCallSite |
一个
VolatileCallSite 是
CallSite 其目标行为一个volatile变量一样。
|
异常 | 描述 |
---|---|
LambdaConversionException |
lambdaconversionexception
|
WrongMethodTypeException |
抛出表示代码试图通过错误的方法类型调用一个方法句柄。
|
java.lang.invoke
包中包含的动态语言支持的java核心类库和虚拟机直接提供。
在java虚拟机的规范描述,这个包一定类型的虚拟机有特殊关系的动态语言支持:
MethodHandle
包含signature polymorphic methods可以链接不论其类型说明符。通常情况下,方法键需要类型描述符的精确匹配。MethodHandle
和MethodType
立即常数。invokedynamic
指令被称为动态调用站点。
invokedynamic
指令在JVM可以执行动态调用网站(一个invokedynamic
指令),调用点必须首先联系。连接是通过调用一个方法进行调用的网站静态信息内容来完成的,而必须产生一个method handle
使调用网站的行为。
每个invokedynamic
指令静态指定自己的Bootstrap方法作为一个常量池参考。常量池引用还指定调用站点的名称和类型说明符,就像invokevirtual
和其他调用指令。
将首先解决了Bootstrap方法的常量池入口,以及解决的动态调用站点类型说明符的一MethodType
对象。这个分辨率的过程可能会触发类加载。因此,它可能会抛出一个错误,如果一个类无法加载。此错误将成为动态调用站点执行的异常终止。关联不触发类初始化。
引导方法至少在三个值上调用:
MethodHandles.Lookup
,对其中发生的动态调用网站查找对象调用类String
,在调用点提到的方法的名称MethodType
,解决类型说明符的电话MethodHandle.invoke
。返回的结果必须是一个
CallSite
(或子类)。调用站点的目标类型必须完全等于来自动态调用站点的类型描述符的类型,并传递给引导方法。然后将该呼叫站点永久地连接到动态呼叫站点。
在Java虚拟机规范的记录,从一个动态调用网站的联动所产生的所有的失败都是由一个BootstrapMethodError
报道,这被作为动态调用执行异常终止。如果发生这种情况,则将引发相同的错误,以执行动态调用站点的所有后续尝试。
如果有几个这样的线程,引导方法可以同时在多个线程中调用。因此,访问全局应用程序数据的引导方法必须采取针对竞争条件的通常的预防措施。在任何情况下,每一invokedynamic
指令是链接或链接到一个独特的CallSite
对象。
在一个应用程序,需要单独的行为动态调用的网站,他们的引导方法产生不同的CallSite
对象,每一个连接请求。另外,应用程序可以单CallSite
对象链接到几个invokedynamic
指令,在这种情况下,改变目标的方法将在每个指令变得可见。
如果多个线程同时执行一个方法为一个单一的动态调用站点,JVM必须选择一个CallSite
对象并安装它明显的所有线程。任何其他方法调用可以完成,但其结果是不容忽视的,其动态调用站点调用进行最初选择的目标对象。
讨论:这些规则不允许JVM复制动态调用的网站,或者发出“电话无缘无故”的引导方法。每一个动态调用站点转换最多一次从链接的链接,就在第一次调用。没有办法撤消已完成的引导方法调用的效果。
MethodHandle.invoke
,其详细的类型是任意的。例如,第一个参数可以代替
MethodHandles.Lookup
Object
,和返回类型也可以代替
CallSite
Object
。(注意,和堆叠的参数个数的限制类型的Bootstrap方法的法律类型适当类型的静态方法,子类的构造函数
CallSite
。)
如果一个给定的invokedynamic
指令指定没有静态参数,指导的方法将三个参数调用,传达指令的调用类,名称,类型和方法。如果invokedynamic
指令指定一个或多个静态参数,这些值将作为额外的参数传递的方法处理。(注意,因为有一个限制的255参数的任何方法,最多251个额外的参数可以提供,因为Bootstrap方法处理本身和它的三个参数也必须堆叠。)引导的方法会被调用,如果通过MethodHandle.invoke
或invokeWithArguments
。(没有办法说出这些区别。)
正常参数转换规则适用于所有的争论MethodHandle.invoke
堆叠。例如,如果一个被推的值是一个原始类型,它可以转换为一个引用,通过装箱转换。如果引导的方法是可变数量的方法(其修改位0x0080
设置),然后一些或所有指定的参数可以被收集到一个拖曳阵列参数。(这是不是一个特别的规则,而是一个有用的结果之间的相互作用CONSTANT_MethodHandle
常数变元数方法,修改点和asVarargsCollector
转化。)
鉴于这些规则,这是法律的Bootstrap方法声明的示例,给出了不同数量N
额外的参数。第一行(标记*
)将为任何数目的额外参数的工作。
N | sample bootstrap method |
---|---|
* | CallSite bootstrap(Lookup caller, String name, MethodType type, Object... args) |
* | CallSite bootstrap(Object... args) |
* | CallSite bootstrap(Object caller, Object... nameAndTypeWithArgs) |
0 | CallSite bootstrap(Lookup caller, String name, MethodType type) |
0 | CallSite bootstrap(Lookup caller, Object... nameAndType) |
1 | CallSite bootstrap(Lookup caller, String name, MethodType type, Object arg) |
2 | CallSite bootstrap(Lookup caller, String name, MethodType type, Object... args) |
2 | CallSite bootstrap(Lookup caller, String name, MethodType type, String... args) |
2 | CallSite bootstrap(Lookup caller, String name, MethodType type, String x, int y) |
CONSTANT_String
和
CONSTANT_Integer
,分别。第二个例子假设所有额外的参数的类型
CONSTANT_String
。其他的例子与所有类型的额外的参数一起工作。
如上所述,引导方法的实际方法类型可能会有所不同。例如,第四个参数可以MethodHandle
,如果是在CONSTANT_InvokeDynamic
进入相应的常量的类型。在这种情况下,该MethodHandle.invoke
呼叫将通过额外的方法处理常量作为Object
,但MethodHandle.invoke
型匹配机械将参考回MethodHandle
Bootstrap方法之前调用。(如果一个字符串常量代替,由差生成的代码,通过投就会失败,导致BootstrapMethodError
。)
请注意,由于上述规则的结果,引导方法可以接受一个原始的参数,如果它可以由一个常量池条目表示。然而,boolean
型,byte
,short
论点,或char
不能引导的方法,因为这些常量不能在常量池直接表示,和Bootstrap方法的调用将不会执行必要的窄化转换。
额外的Bootstrap方法的参数都是为了让语言实现安全、简洁编码元数据。在原则上,名称和额外的参数是多余的,因为每个调用的网站可以给自己独特的引导方法。这样的做法很可能会产生大量的类文件和常量池。
Submit a bug or feature
For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.
Copyright © 1993, 2014, Oracle and/or its affiliates. All rights reserved.