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

最佳答案

使用代码

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以获取更多说明和示例。

    10-07 13:04