我试图检查是否可以使用 MethodHandle::invoke 或 MethodHandle::invokeExact 作为接受 MethodHandle 并返回通用输出的功能接口的方法引用。
(我知道 invoke 和 invokeExact 是签名多态的,因此 InvokeExact 中的元工厂调用。但是,我想知道编译器是否能够省略我必须做的事情来派生一个合适的 invoke/invokeExact 版本。)
调用.InvokeExact0
package invoke;
import java.lang.invoke.MethodHandle;
import static java.lang.System.out;
import static java.lang.invoke.LambdaMetafactory.metafactory;
import static java.lang.invoke.MethodHandles.lookup;
import static java.lang.invoke.MethodType.methodType;
@FunctionalInterface
public interface InvokeExact0<OUTPUT> {
public OUTPUT invokeExact(MethodHandle methodHandle) throws Throwable;
public static <OUTPUT> InvokeExact0<OUTPUT> new_(InvokeExact0<OUTPUT> invokeExact) {
return invokeExact;
}
public static void main(String... arguments) throws Throwable {
out.println(
(InvokeExact0<String>) metafactory(
lookup(),
"invokeExact",
methodType(InvokeExact0.class),
methodType(
Object.class,
MethodHandle.class
),
lookup().findVirtual(
MethodHandle.class,
"invokeExact",
methodType(String.class)
),
methodType(
String.class,
MethodHandle.class
)
)
.getTarget()
.invokeExact()
);
out.println(InvokeExact0.new_(MethodHandle::invokeExact));
}
}
Result
invoke.InvokeExact0$$Lambda$1/1878246837@5ca881b5
Exception in thread "main" java.lang.BootstrapMethodError: call site initialization exception
at java.lang.invoke.CallSite.makeSite(CallSite.java:328)
at java.lang.invoke.MethodHandleNatives.linkCallSite(MethodHandleNatives.java:296)
at invoke.InvokeExact0.main(InvokeExact0.java:41)
Caused by: java.lang.invoke.LambdaConversionException: Incorrect number of parameters for instance method invokeVirtual java.lang.invoke.MethodHandle.invokeExact:(MethodH
andle)Object; 0 captured parameters, 1 functional interface method parameters, 1 implementation parameters
at java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:193)
at java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:303)
at java.lang.invoke.CallSite.makeSite(CallSite.java:289)
... 2 more
好消息是元工厂方法能够合成一个工作功能接口实例(如下所示:invoke.InvokeExact0$$Lambda$1/1878246837@1be6f5c3)。
坏消息是方法引用方法导致 LambdaConversionException,进而导致 BootstrapMethodError。
然后我想问我应该如何解释 LambdaConversionException 中的错误详细信息,因为元工厂解决方法无论如何都存在。