2015-09-04 5 views
3

Я пытаюсь выполнить аннотированный метод в основном методе в App.java с LambdaMetafactory.metafactory(). Код можно найти здесь: code on githubКак разрешить неправильные параметры из LambdaMetafactory

Если я пытаюсь выполнить этот код он будет бросать исключение:

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

Не просто ссылку на домашнюю страницу всего проекта. Отправьте сюда код, о котором идет речь. –

ответ

2

ошибка пытается сказать вам, не проходя еще параметры. Он ожидает одного, но вы его не передаете.

Предлагаю вам ознакомиться с параметрами, которые вы передаете, и сравнить их с фактически переданными параметрами при построении лямбда.

Напишите, что вы пытаетесь сделать, и лямбда сначала, и посмотрите, какие параметры вы должны пройти.

+0

Я не мог найти ошибку в параметрах, поэтому я попросил помочь с кодом выше. –

+0

@ EvgeniyFitsner вы попробовали мое предложение сравнить ваши данные с теми, которые генерирует компилятор? –

+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 для получения дополнительных пояснений и примеров.