JEP 274:增强的方法句柄
概括
增强包的MethodHandle
、MethodHandles
和MethodHandles.Lookup
类,java.lang.invoke
以简化常见用例,并通过新的MethodHandle
组合器和查找细化实现更好的编译器优化。
目标
-
在包
MethodHandles
中的类中,为循环和 try/finally 块java.lang.invoke
提供新的组合器。MethodHandle
-
使用用于参数处理的新组合器增强
MethodHandle
和类。MethodHandles``MethodHandle
-
对类中的接口方法和(可选)超级构造函数实现新的查找
MethodHandles.Lookup
。
非目标
-
除了可能需要的本机功能之外,VM 级扩展和增强(特别是编译器优化)并不是目标。
-
Java 语言级别的扩展显然超出了范围。
动机
在邮件列表上的一个线程mlvm-dev
(第 1 部分、第 2 部分)中,开发人员讨论了包中MethodHandle
、MethodHandles
、 和MethodHandles.Lookup
类的可能扩展java.lang.invoke
,以使常见用例的实现更容易,并且还允许被认为重要但但不重要的用例。目前不支持。
下面提出的扩展不仅允许更简洁地使用 API ,而且还减少了在某些情况下创建的实例MethodHandle
数量。MethodHandle
反过来,这将有助于虚拟机编译器更好的优化。
更多语句的组合器
**循环。**该类MethodHandles
没有为MethodHandle
实例的循环构造提供抽象。应该有一种方法可以从MethodHandle
表示循环体的 s 构造循环,以及初始化和条件或计数。
Try/finally 块。 MethodHandles
也没有为 try/finally 块提供抽象。应该提供一种从表示try
和部分的方法句柄构造此类块的方法。finally
更好的参数处理
**争论蔓延。**对于MethodHandle.asSpreader(Class<?> arrayType, int arrayLength)
,存在一个创建方法句柄的操作,该方法句柄会将_尾随_数组参数的内容扩展到多个参数。应该提供一个附加asSpreader
方法,允许将方法签名中任意位置的数组中包含的多个参数扩展为多个不同的参数。
**论据收集。**该方法MethodHandle.asCollector(Class<?> arrayType, int arrayLength)
生成一个句柄,将尾随 arrayLength
参数收集到一个数组中。对于方法签名中其他地方的许多参数,无法实现相同的效果。应该有一个额外的asCollector
方法来支持这一点。
**论证折叠。**折叠组合器foldArguments(MethodHandle target, MethodHandle combinator)
不允许控制参数列表中折叠开始的位置。应添加位置参数;要折叠的参数数量隐式给出为接受的参数数量combinator
。
更多查找功能
**接口中的非抽象方法。**目前,像这样的用例将在运行时在指定位置失败:
interface I1 {
default void m() { System.err.println("I1.m"); }
}
interface I2 {
default void m() { System.err.println("I2.m"); }
}
class C implements I1, I2 {
public void m() { I2.super.m(); System.err.println("C.m"); }
}
public class IfcSuper {
public static void main(String[] args) throws Throwable {
C c = new C();
MethodHandles.Lookup l = MethodHandles.lookup();
MethodType t = MethodType.methodType(void.class);
// This lookup will fail with an IllegalAccessException.
MethodHandle di1m = l.findSpecial(I1.class, "m", t, C.class);
ci1m.invoke(c);
}
}