我尝试使用 LambdaMetafactory.metafactory()在App.java中的main方法中执行带注释的方法。代码可以在这里找到:code on github
如果我试图执行此代码,它会抛出异常:
Incorrect number of parameters for instance method invokeVirtual com.drfits.transfer.TransferExecutorImpl.execute:(Transfer)void; 0 captured parameters, 1 functional interface method parameters, 1 implementation parameters
答案 0 :(得分:3)
使用代码
TransferExecutor transferExecutor= new TransferExecutorImpl();
Function<Transfer, Void> commonLambda = transferExecutor::execute;
您将Function
绑定到TransferExecutor
的特定实例。您的动态创建代码缺少用于调用实例方法TransferExecutorImpl.execute
的实例。这就是异常试图告诉你的。
实例方法需要调用目标实例,因此您的目标方法的函数签名为(TransferExecutor,Transfer)→Void
。
您可以使用此方法创建BiFunction<TransferExecutor,Transfer, Void>
,也可以使用transferExecutor::execute
方法引用将实例绑定到该方法。对于后者
更改调用的类型以接收TransferExecutor
MethodType invokedType = MethodType.methodType(
Function.class, TransferExecutorImpl.class);
在调用时提供参数:
… .getTarget().invokeExact((TransferExecutorImpl)transferExecutor);
请注意,仍然存在细微差别。语句Function<Transfer, Void> commonLambda = transferExecutor::execute;
引用接口方法,而通过注释识别的方法是TransferExecutorImpl
中声明的方法。
关于绑定捕获的值,请参阅this和that answer以获取更多说明和示例。
答案 1 :(得分:2)
该错误试图告诉您没有传递其他参数。它期待一个,但你没有传递它。
我建议您查看传递的参数,并将它们与构建lambda时实际传递的参数进行比较。
首先写下你要做的事情和一个lambda,看看你应该传递什么参数。