如何从LambdaMetafactory中解析不正确的参数

时间:2015-09-04 06:55:21

标签: java lambda method-reference

我尝试使用 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

2 个答案:

答案 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中声明的方法。

关于绑定捕获的值,请参阅thisthat answer以获取更多说明和示例。

答案 1 :(得分:2)

该错误试图告诉您没有传递其他参数。它期待一个,但你没有传递它。

我建议您查看传递的参数,并将它们与构建lambda时实际传递的参数进行比较。

首先写下你要做的事情和一个lambda,看看你应该传递什么参数。