3

我正在尝试使用LambdaMetafactory.metafactory()在 App.java 的 main 方法中执行带注释的方法。代码可以在这里找到: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
4

2 回答 2

4

使用代码

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.

关于绑定捕获的值,请参阅这个那个答案以获得更多解释和示例。

于 2015-09-23T14:04:23.990 回答
1

该错误试图告诉您没有传递其他参数。它需要一个,但你没有通过它。

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

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

于 2015-09-04T06:58:22.833 回答